{
  "openapi": "3.1.0",
  "info": {
    "title": "Stabiso",
    "description": "Stabiso is an Enterprise System of Record (ESoR): one headless, double-entry system of record\nfor finance and sales, built for humans and AI agents.\n\n* **Integrity in the database**: posted entries balance, are immutable and form a\n  tamper-evident hash chain; closed periods reject postings.\n* **Explainable**: every posting stores its provenance, including the data-vNext\n  dataset version, tax rule and FX fixing it used.\n* **Agent-ready**: scoped API keys, an approval policy, `Idempotency-Key` on writes,\n  a complete audit trail, and the same operations as MCP tools at `/mcp`.\n",
    "version": "0.1.0"
  },
  "paths": {
    "/forms/leads/{key}": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Send a lead from a website",
        "description": "No credential: the key names the form. Whoever fills in the form becomes a lead of the\nform's company (status `new`, source `web_form`, owned by the form's owner). Limited per client\naddress and per form (429 with `Retry-After`).",
        "operationId": "submit_forms_leads__key__post",
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The form's public key (`GET /v1/lead-forms`).",
              "examples": [
                "lf_0b9c4a2e7d1f4e3a9c5b6d7e8f9a0b1c_Qm3xV7pL2sK9tR4wY8zN1a"
              ],
              "title": "Key"
            },
            "description": "The form's public key (`GET /v1/lead-forms`)."
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Language of an HTML answer.",
              "title": "Lang"
            },
            "description": "Language of an HTML answer."
          }
        ],
        "responses": {
          "201": {
            "description": "Received (also when dropped as spam: a robot learns nothing). JSON to a script; the form's thank-you page to the form's own page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "received": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "received": true
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "303": {
            "description": "Received from a website's own HTML form: to its `redirect_url`."
          },
          "403": {
            "description": "`lead_form_origin`: not sent from one of the form's websites."
          },
          "404": {
            "description": "`lead_form_unknown`: no such form, or it is switched off."
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope."
          },
          "429": {
            "description": "`rate_limited`: too many submissions; see `Retry-After`."
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "description": "`first_name`, `last_name` (or `name`, split at its last word), `email` (required), `company`, `role`, `phone`, `country` (ISO 3166-1), `message`, `campaign` (the lead's source detail; default: the form's name) and `website`, a field to hide from people and leave empty (a submission that fills it is dropped). JSON from a script, or `application/x-www-form-urlencoded` from an HTML form.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string"
                  },
                  "company": {
                    "type": "string"
                  },
                  "role": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  },
                  "campaign": {
                    "type": "string"
                  },
                  "website": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "first_name": "Eva",
                "last_name": "Beispiel",
                "email": "eva@beispiel.example",
                "company": "Beispiel GmbH",
                "message": "Please send us a quote for 25 seats."
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "email"
                ],
                "properties": {
                  "first_name": {
                    "type": "string"
                  },
                  "last_name": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "email": {
                    "type": "string"
                  },
                  "company": {
                    "type": "string"
                  },
                  "role": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  },
                  "campaign": {
                    "type": "string"
                  },
                  "website": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "first_name": "Eva",
                "last_name": "Beispiel",
                "email": "eva@beispiel.example",
                "company": "Beispiel GmbH",
                "message": "Please send us a quote for 25 seats."
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/health": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "Check that the service is running",
        "description": "Liveness check for monitors and load balancers: `{\"status\": \"ok\"}` with status 200 whenever the process answers. It needs no API key and does not touch the database.",
        "operationId": "healthz_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "type": "object",
                  "title": "Response Healthz Health Get"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/v1/access-log": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "List what external auditors opened",
        "description": "Every request of the organization's external auditors, newest first: when, who, what they\nopened (method, path and query: a screen's data, a report, a downloaded file) and the answer's\nstatus (403 for what was refused them). An external auditor is a person invited with an end\nto their access (`access_until`) or with the rights to read and to audit only (the `auditor`\nrole). The log is append-only; nobody can change or delete it. Only a person with the admin\nscope reads it (403 otherwise).",
        "operationId": "access_log_v1_access_log_get",
        "parameters": [
          {
            "name": "user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the requests of this auditor (a user id from `GET /v1/users`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "User Id"
            },
            "description": "Only the requests of this auditor (a user id from `GET /v1/users`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "Most entries returned, 1 to 1000.",
              "default": 100,
              "title": "Limit"
            },
            "description": "Most entries returned, 1 to 1000."
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Continue before this entry (its `id`, the last of the previous page); omit for the newest.",
              "title": "Before"
            },
            "description": "Continue before this entry (its `id`, the last of the previous page); omit for the newest."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AccessLogEntry"
                  },
                  "title": "Response Access Log V1 Access Log Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/activities": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List activities",
        "description": "The timeline of a deal, a lead or a customer, or the open tasks: the newest first (open\ntasks: the earliest due first). Someone who sees only their own or their team's records gets\nthe activities of those people, the tasks assigned to them and the timelines of the deals,\nleads and customers they see. Read-only.",
        "operationId": "list_activities_v1_activities_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's activities (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's activities (code or id)."
          },
          {
            "name": "opportunity_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this deal's.",
              "title": "Opportunity Id"
            },
            "description": "Only this deal's."
          },
          {
            "name": "party_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's.",
              "title": "Party Id"
            },
            "description": "Only this customer's."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "call",
                    "email",
                    "meeting",
                    "note",
                    "task"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this kind.",
              "title": "Kind"
            },
            "description": "Only this kind."
          },
          {
            "name": "open_tasks",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only tasks not done yet.",
              "default": false,
              "title": "Open Tasks"
            },
            "description": "Only tasks not done yet."
          },
          {
            "name": "assignee_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only tasks of this person.",
              "title": "Assignee User Id"
            },
            "description": "Only tasks of this person."
          },
          {
            "name": "contact_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those with this contact (`GET /v1/contacts`).",
              "title": "Contact Id"
            },
            "description": "Only those with this contact (`GET /v1/contacts`)."
          },
          {
            "name": "owner_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those this person did or set (`GET /v1/people`).",
              "title": "Owner User Id"
            },
            "description": "Only those this person did or set (`GET /v1/people`)."
          },
          {
            "name": "lead_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this lead's (`GET /v1/leads`).",
              "title": "Lead Id"
            },
            "description": "Only this lead's (`GET /v1/leads`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, the newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ActivityOut"
                  },
                  "title": "Response List Activities V1 Activities Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Record an activity",
        "description": "A note, call, meeting or e-mail about a deal (`opportunity_id`) or a customer (`entity`\nand `party`), or a task with its due day and assignee (by default the deal's owner). An\nactivity is never edited or deleted; a task is completed once\n(`POST /v1/activities/{activity_id}/complete`). Needs an `Idempotency-Key`.",
        "operationId": "create_activity_v1_activities_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivityInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/activities/{activity_id}/complete": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Mark a task done",
        "description": "Record that a task is done, by whom and when. 409 for an activity that is not a task or a\ntask already done; 404 when it does not exist.",
        "operationId": "complete_activity_v1_activities__activity_id__complete_post",
        "parameters": [
          {
            "name": "activity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the activity (`GET /v1/activities`).",
              "examples": [
                "4a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d"
              ],
              "title": "Activity Id"
            },
            "description": "Id of the activity (`GET /v1/activities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/addresses/details": {
      "get": {
        "tags": [
          "addresses"
        ],
        "summary": "Get the parts of a suggested address",
        "description": "The street, building number, postal code, town, canton or state and country of the address\nchosen, to fill a form with. 404 `address_not_found` when the server suggests no addresses\nor Google does not know or give it. An organization may ask for 2,000 a day.",
        "operationId": "address_details_v1_addresses_details_get",
        "parameters": [
          {
            "name": "session",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{8,64}$",
              "description": "A token the caller makes once per address typed (a UUID) and sends with every suggestion and the details of the one chosen: Google charges the address chosen, not the suggestions before it.",
              "title": "Session"
            },
            "description": "A token the caller makes once per address typed (a UUID) and sends with every suggestion and the details of the one chosen: Google charges the address chosen, not the suggestions before it."
          },
          {
            "name": "suggestion",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,300}$",
              "description": "The `id` of a suggestion of `GET /v1/addresses/suggestions`.",
              "title": "Suggestion"
            },
            "description": "The `id` of a suggestion of `GET /v1/addresses/suggestions`."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{2}(-[A-Za-z]{2})?$",
              "description": "The language of the names (`de`).",
              "default": "en",
              "title": "Language"
            },
            "description": "The language of the names (`de`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/addresses/suggestions": {
      "get": {
        "tags": [
          "addresses"
        ],
        "summary": "Suggest addresses",
        "description": "At most five whole addresses that match what was typed (streets with or without a number,\nno shops or sights), best first, from Google's Places API. `available` is false on a server\nwithout its key; the list is then empty, as it is when Google does not answer. An\norganization may ask for 5,000 a day (429 `rate_limited` after).",
        "operationId": "suggest_addresses_v1_addresses_suggestions_get",
        "parameters": [
          {
            "name": "session",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{8,64}$",
              "description": "A token the caller makes once per address typed (a UUID) and sends with every suggestion and the details of the one chosen: Google charges the address chosen, not the suggestions before it.",
              "title": "Session"
            },
            "description": "A token the caller makes once per address typed (a UUID) and sends with every suggestion and the details of the one chosen: Google charges the address chosen, not the suggestions before it."
          },
          {
            "name": "text",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 120,
              "description": "What was typed so far; under three characters nothing is asked of Google (empty: only whether addresses are suggested here).",
              "default": "",
              "title": "Text"
            },
            "description": "What was typed so far; under three characters nothing is asked of Google (empty: only whether addresses are suggested here)."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([A-Za-z]{2})?$",
              "description": "Only addresses in this country (ISO 3166-1 alpha-2); empty: anywhere.",
              "default": "",
              "title": "Country"
            },
            "description": "Only addresses in this country (ISO 3166-1 alpha-2); empty: anywhere."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{2}(-[A-Za-z]{2})?$",
              "description": "The language of the names (`de`).",
              "default": "en",
              "title": "Language"
            },
            "description": "The language of the names (`de`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddressSuggestionsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/addresses/towns": {
      "get": {
        "tags": [
          "addresses"
        ],
        "summary": "Find the town of a postal code",
        "description": "The towns a postal code covers, each with its canton or state, from open postal code data\nshipped with Stabiso (no call to anyone): AT, BE, CH, DE, DK, ES, IT, LI, LU, NL, NO, SE and\nUS (the state only). Empty for an unknown code or another country.",
        "operationId": "postal_code_towns_v1_addresses_towns_get",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z]{2}$",
              "description": "The country, ISO 3166-1 alpha-2 (`CH`).",
              "title": "Country"
            },
            "description": "The country, ISO 3166-1 alpha-2 (`CH`)."
          },
          {
            "name": "postal_code",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 16,
              "description": "The postal code (`8001`).",
              "title": "Postal Code"
            },
            "description": "The postal code (`8001`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PostalTownsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/agents/ask": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Ask a question about the books",
        "description": "Answer a question about the books with read-only tools; figures cite entries.\n\nA language model looks the figures up in the ledger, subledgers and reports and answers in\nprose. `citations` are the entry and document numbers the tools actually returned;\n`unverified_references` are numbers in the answer that no tool returned and should be\nchecked. `tool_calls` is what the agent looked at. It cannot change anything. Answers 502\nwhen the model fails and 503 when no language model is configured on the server.",
        "operationId": "ask_books_v1_agents_ask_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Answer"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/agents/assistant": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Talk to the assistant",
        "description": "One turn of a conversation with the assistant: the answer to the person's last message.\n\nA language model works in the books with the same tools an MCP client has, as an agent\nacting for the caller: it looks figures up, answers with charts (`charts`; each value no tool\nreturned is listed in the chart's `unverified`), and with `draft` it may create and change\nrecords and run the period-end steps, whose postings wait for approval where the policy says\nso; with `read` only it reads. It asks before it changes anything and answers in `language`.\nWith `period_id` it closes that period with the person: `close` gives the checklist's state\nafter the turn and the open steps only a person can take, each with its place in the app; the\nassistant never closes a period. The conversation is not stored: send what was said so far\nwith each message. Answers 404 for an unknown period or company, 502 when the model fails and\n503 when no language model is configured.",
        "operationId": "talk_to_the_assistant_v1_agents_assistant_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssistantRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssistantReply"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/agents/assistant/stream": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Talk to the assistant, with its progress",
        "description": "`POST /v1/agents/assistant`, answered as it works: the person sees what the assistant does.\n\nThe same turn as `POST /v1/agents/assistant`, as `application/x-ndjson`: a `step` line for\neach tool the assistant calls (its name and area, e.g. `bank`, `vat`, `trends`), a `working`\nline every few seconds while the model thinks, and a last line `done` with the answer or\n`error` with the status and error an ordinary request would have answered (502 when the\nmodel fails, `model_busy` when it is overloaded, 503 when no model is configured). An unknown\nperiod or company is a 404 before anything is streamed.",
        "operationId": "talk_to_the_assistant_streaming_v1_agents_assistant_stream_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssistantRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One JSON object per line: `step` for each tool the assistant calls (`tool`, `area`), `working` every few seconds while it thinks, then `done` with the answer (the fields of `AssistantReply`) or `error` (`status`, `error`).",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/agents/bill-capture": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Capture a vendor bill from a file",
        "description": "Read a vendor invoice into a draft bill (VAT re-determined) queued for approval.\n\nSend the file as `multipart/form-data`. The agent reads it with a language model, matches\nor creates the vendor, determines the VAT again for every line and submits the bill as an\nagent, so it always waits for a human approval (`status` `pending_approval`) with the\nevidence attached; `warnings` lists what to check. XRechnung XML and PDFs with embedded\nZUGFeRD / Factur-X data are booked from the XML without a model call (`source`\n`einvoice`). A file read before with `POST /v1/agents/bill-capture/read` is booked from that\nreading, without asking the model again. A file that is not an invoice answers\n`not_an_invoice`. Refused with 409 when\nthe same file was captured before, 422 for an unsupported or oversized file, 502 when the\nmodel fails, and 503 when no language model is configured on the server (e-invoices need\nnone).",
        "operationId": "capture_bill_v1_agents_bill_capture_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_capture_bill_v1_agents_bill_capture_post"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaptureResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/agents/bill-capture/read": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Read a vendor bill without booking it",
        "description": "Read a vendor invoice and say what it is, before anything is booked.\n\nThe first step of the bill wizard. An e-invoice is read from its XML (and checked against\nthe EN 16931 and XRechnung rules, `einvoice`); any other PDF or image is read by the\nlanguage model, and the reading is stored with the file (`document_id`). The answer names\nthe known vendor the bill matches (`vendor`) or, for an unknown one, its master data as\nprinted (`new_vendor`, to create it with `POST /v1/entities/{entity}/parties`), and whether\na bill can be made from it (`bookable`). Book it with `POST /v1/agents/bill-capture` and the\nsame file: the stored reading is used, the model is not asked again. Nothing is booked and\nno vendor is created here. When no language model answers in time, nothing is read or stored\nand the answer is `status` `waiting`: send the file again after `retry_after_seconds`.\nRefused with 409 when the file already has a bill, 422 for an unsupported or oversized file,\n502 when the model fails otherwise and 503 when no language model is configured (e-invoices\nneed none).",
        "operationId": "read_bill_v1_agents_bill_capture_read_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_read_bill_v1_agents_bill_capture_read_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillReading"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/agents/entities/{entity}/reconcile": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Propose bank reconciliations",
        "description": "Propose matches or postings for the entity's unmatched bank lines, oldest first.\n\nFor each line a language model, shown the line, its scored candidate invoices and bills and\nthe postable accounts, proposes to `match` documents, `post` to an account, or `leave` the\nline. Every proposal is checked in code before it is used. With `apply` true, valid\nproposals at or above `min_confidence` are carried out as the reconciliation agent, which\ncannot post, so each one waits for a human approval (`status` `pending_approval`); the\nothers come back as `proposed`, `rejected` or `left`. Answers 502 when the model fails and\n503 when no language model is configured on the server.",
        "operationId": "reconcile_bank_v1_agents_entities__entity__reconcile_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReconcileRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReconcileResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/agents/form-suggestions": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Suggest what to enter in a form",
        "description": "Propose values for a form's fields from what they are for and the company.\n\nThe screen sends what the form creates and each field with its explanation, options and what\nwas entered so far; a language model proposes a value and a one-sentence reason for each field\nit can, in the language asked. Nothing is saved: the screen fills the form and the person\nchecks it before saving. Facts only the person knows (names, addresses, amounts, bank\ndetails) are left out, a choice outside its options or a number that is not one is dropped.\nWhen no model answers in time the answer is `status: \"waiting\"` with `retry_after_seconds`;\n503 when no language model is configured on the server.",
        "operationId": "suggest_form_values_v1_agents_form_suggestions_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FormSuggestionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FormSuggestions"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/agents/periods/{period_id}/close-review": {
      "post": {
        "tags": [
          "agents"
        ],
        "summary": "Review a period before closing",
        "description": "Prepare a period for closing and write the close memo. It never locks the period.\n\nA language model works through the close checklist, the flux analysis, the unusual entries\nand the subledger ties with read-only tools, may run depreciation and FX revaluation when\n`run_adjustments` is true (queued for approval, not posted), records `issues` (blocker,\nwarning or info) and writes the memo in Markdown, which is also stored as a document\n(`memo_document_id`). `ready` is true only when the checklist is ready and no issue is a\nblocker. A human closes the period (`POST /v1/periods/{period_id}/close`). Answers 404 for\nan unknown period, 502 when the model fails or answers with no memo (nothing is stored then)\nand 503 when no language model is configured.",
        "operationId": "review_close_v1_agents_periods__period_id__close_review_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloseReviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CloseReview"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "The agents are not configured on this server (`agents_unavailable`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/api-keys": {
      "get": {
        "tags": [
          "organization"
        ],
        "summary": "List API keys",
        "description": "The organization's API keys: name, actor type, scopes, created, last used, revoked.\n\nNever the secret or its hash; `prefix` identifies a key in the audit trail (`key:<prefix>`).",
        "operationId": "list_keys_v1_api_keys_get",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "revoked"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only `active` or only `revoked` keys; omit for all of them.",
              "examples": [
                "active"
              ],
              "title": "Status"
            },
            "description": "Only `active` or only `revoked` keys; omit for all of them."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/KeyInfo"
                  },
                  "title": "Response List Keys V1 Api Keys Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "post": {
        "tags": [
          "organization"
        ],
        "summary": "Issue an API key",
        "description": "Issue an API key for a person or a system, e.g. a scoped key for an AI agent.\n\nThe secret is in `key` of the response and is shown only now: the server keeps just its\nhash. Send it as `Authorization: Bearer <key>` or `X-API-Key`. Only a human with the admin\nscope may issue keys (403 otherwise). An agent key may not hold the `approve` or `admin`\nscope (422), so an agent can never approve its own work. Issuing a key is an audit event.",
        "operationId": "create_key_v1_api_keys_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/KeyRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/api-keys/{key_id}": {
      "get": {
        "tags": [
          "organization"
        ],
        "summary": "Get an API key",
        "description": "One API key of the organization, without its secret. A key of another organization, or\nan unknown id, answers 404.",
        "operationId": "get_key_v1_api_keys__key_id__get",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "API key id (`GET /v1/api-keys`), not the secret.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Key Id"
            },
            "description": "API key id (`GET /v1/api-keys`), not the secret."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/KeyInfo"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "delete": {
        "tags": [
          "organization"
        ],
        "summary": "Revoke an API key",
        "description": "Revoke a key. From then on requests with it answer 401; the key stays listed with\nstatus `revoked`. Only a human with the admin scope may revoke keys (403 otherwise). The\nresponse has no body. Revoking is an audit event.",
        "operationId": "revoke_key_v1_api_keys__key_id__delete",
        "parameters": [
          {
            "name": "key_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "API key id (`GET /v1/api-keys`), not the secret.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Key Id"
            },
            "description": "API key id (`GET /v1/api-keys`), not the secret."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/applications": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Apply an amount on account or a credit note to open documents",
        "description": "Apply what is left on account of a posted payment or receipt (`payment`), or the open\namount of a posted credit note (`credit_note`), to open posted invoices or bills of the same\ncustomer or vendor, on `application_date`; a document in another currency is settled by the\n`document_amount` its allocation names in that currency (ADR-0054). One allocation per document\nand one entry that moves the amount on the control account from the payment or credit note to\nthe documents; each side is relieved at the rate it is carried at (the payment's, the credit\nnote's, the document's historical rate) and the difference is booked as realised FX. The entry\ngoes through the approval policy (`submit.policy`); until it is posted the amounts are reserved\non both sides. Refuses with 422 when the amounts are more than is left to apply or open on a\ndocument, a document cannot be settled by it (other party, kind or status), or the\ndate is before the payment, the credit note or a document; with 404 for an unknown payment,\ncredit note or document; with 409 when the period is closed, or a bill is blocked for payment\n(`bill_payment_blocked`: its purchase order variance waits for a second person's approval, as\nfor a payment). All or nothing.",
        "operationId": "create_application_v1_applications_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplicationInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApplicationResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/approval-policy": {
      "get": {
        "tags": [
          "approval policy"
        ],
        "summary": "Get the approval policy",
        "description": "The approval policy in force: a decision table over actor type, action, amount and\nsource whose first matching rule decides `allow`, `require_approval` or `deny`.\n\n`source` says whether it is the `default` table or the organization's own; `version` is 0\nuntil the first change. The response carries an `ETag` header (e.g. `\"policy-3\"`): send it\nas `If-Match` with `PUT` or `DELETE` to change the policy only if nobody else did in the\nmeantime. `actions` lists every action the services ask about, `agents_always_denied`\nthose no table may allow agents.",
        "operationId": "get_policy_v1_approval_policy_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalPolicyOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "approval policy"
        ],
        "summary": "Replace the approval policy",
        "description": "Replace the organization's policy with a decision table. Only a human with the admin\nscope may do this (403 otherwise).\n\nThe table is validated (422 with the list of `problems`): it must declare the four inputs\n`actor_type`, `action`, `amount` and `source` (optionally `actor_name`, a system process's\nname or else the actor id, never required and tested only with a literal or `in`) and a\n`decision` output, list every action,\nand deny agents every action but `post`, whatever the rules say. Each change is a new\nversion and an audit event. Send the `ETag` you read in `If-Match`: when the policy has\nmoved on, the answer is 412 and nothing changes. The response carries the new `ETag`.\n\nA change that relaxes any decision (`deny` to `require_approval` or `allow`, or\n`require_approval` to `allow`, for any actor type, action, amount or source) does not apply\nyet: it becomes an approval request (`change_approval_policy`) that a second person with\nthe admin scope approves under Approvals, never the one who asked and never an agent. The\nresponse keeps the policy in force and shows the request in `pending_change`, with what it\nrelaxes. One such change waits at a time (409 `approval_policy_change_waiting`), until it\nis decided or the person who asked withdraws it (`POST /v1/approvals/{approval_id}/withdraw`;\nan administrator whose colleagues are not administrators has nobody to approve it). A change\nthat only tightens applies at once, and so does any change in an organization with fewer\nthan two active people, unless another user was disabled or lost the admin scope in the\nlast 30 days (audited with what it relaxes).",
        "operationId": "put_policy_v1_approval_policy_put",
        "parameters": [
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The `ETag` of the version you read (`\"policy-3\"`, from `GET /v1/approval-policy`). If the policy has changed since, the call answers 412 and changes nothing. `*` always matches; omitted, the change is made without the check.",
              "examples": [
                "\"policy-3\""
              ],
              "title": "If-Match"
            },
            "description": "The `ETag` of the version you read (`\"policy-3\"`, from `GET /v1/approval-policy`). If the policy has changed since, the call answers 412 and changes nothing. `*` always matches; omitted, the change is made without the check."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PolicyInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalPolicyOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none",
        "x-if-match": "optional"
      },
      "delete": {
        "tags": [
          "approval policy"
        ],
        "summary": "Reset the approval policy",
        "description": "Return to the default policy. Only a human with the admin scope may do this (403\notherwise). It is recorded as a new version, so the history keeps the table that was\nreplaced. Send the `ETag` you read in `If-Match`; a changed policy answers 412. Returns the\ndefault policy with its new `ETag`. If the default is looser than the organization's table\nanywhere, the return waits for a second administrator like any change that relaxes the\npolicy (`pending_change`; see `PUT`).",
        "operationId": "reset_policy_v1_approval_policy_delete",
        "parameters": [
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The `ETag` of the version you read (`\"policy-3\"`, from `GET /v1/approval-policy`). If the policy has changed since, the call answers 412 and changes nothing. `*` always matches; omitted, the change is made without the check.",
              "examples": [
                "\"policy-3\""
              ],
              "title": "If-Match"
            },
            "description": "The `ETag` of the version you read (`\"policy-3\"`, from `GET /v1/approval-policy`). If the policy has changed since, the call answers 412 and changes nothing. `*` always matches; omitted, the change is made without the check."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalPolicyOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/approval-policy/versions": {
      "get": {
        "tags": [
          "approval policy"
        ],
        "summary": "List policy versions",
        "description": "Every change to the organization's policy, newest first, with the table of each.",
        "operationId": "policy_versions_v1_approval_policy_versions_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PolicyVersionOut"
                  },
                  "title": "Response Policy Versions V1 Approval Policy Versions Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/approvals": {
      "get": {
        "tags": [
          "approvals"
        ],
        "summary": "List Approvals",
        "description": "The approval requests of the organization with the given status, oldest first. A\nrequest is created when the approval policy sends an action to a second person, e.g. a\njournal entry or a new vendor; `object_type` and `object_id` say what it is about. With\n`for_me`, also one's own steps the AI reviewer held that one releases oneself, being the\nonly person who could (ADR-0101).",
        "operationId": "list_approvals_v1_approvals_get",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "approved",
                    "pending",
                    "rejected"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`pending` (default), `approved` or `rejected`.",
              "examples": [
                "pending"
              ],
              "default": "pending",
              "title": "Status"
            },
            "description": "`pending` (default), `approved` or `rejected`."
          },
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the requests of this entity (code), the ones the Role Center counts for it. Default: the whole organization.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only the requests of this entity (code), the ones the Role Center counts for it. Default: the whole organization."
          },
          {
            "name": "for_me",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only the requests the caller may decide under the four-eyes principle: not requested, created, prepared or submitted by the caller (whichever key or session); none for a key the system issued. The Role Center's `pending_for_me`.",
              "default": false,
              "title": "For Me"
            },
            "description": "Only the requests the caller may decide under the four-eyes principle: not requested, created, prepared or submitted by the caller (whichever key or session); none for a key the system issued. The Role Center's `pending_for_me`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApprovalOut"
                  },
                  "title": "Response List Approvals V1 Approvals Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/approvals/{approval_id}/approve": {
      "post": {
        "tags": [
          "approvals"
        ],
        "summary": "Approve a request",
        "description": "Approve a pending request; the action it asked for then happens (a journal entry is\nposted, a vendor activated). The body, with an optional comment, may be left out.\n\nRefused with 403 when the caller is the person or key that made the request (`four_eyes`:\na second person must approve, whatever the caller's scopes), lacks the approve scope or is\ndenied by the policy (agents are); with 409\nwhen the request is no longer pending, or when the action fails, e.g. the period is closed\nor a credit note now exceeds what is left to credit on the document it credits (another\ncredit note took it while this one waited; 422 when its lines without an obligation would\ncredit more than the invoice's other lines left).",
        "operationId": "approve_v1_approvals__approval_id__approve_post",
        "parameters": [
          {
            "name": "approval_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Approval request id (`GET /v1/approvals`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Approval Id"
            },
            "description": "Approval request id (`GET /v1/approvals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Decision"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              },
              "example": {
                "comment": "Checked against the vendor statement"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/approvals/{approval_id}/reject": {
      "post": {
        "tags": [
          "approvals"
        ],
        "summary": "Reject a request",
        "description": "Reject a pending request; the action does not happen (a journal entry becomes\n`rejected` and is never posted). The body, with an optional comment saying why, may be\nleft out. The same refusals as approving apply: four-eyes (403), scope or policy (403),\nalready decided (409). The person who asked to raise or remove a posting approval limit or\nto relax the approval policy takes her request back with `POST .../withdraw` instead.",
        "operationId": "reject_v1_approvals__approval_id__reject_post",
        "parameters": [
          {
            "name": "approval_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Approval request id (`GET /v1/approvals`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Approval Id"
            },
            "description": "Approval request id (`GET /v1/approvals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Decision"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              },
              "example": {
                "comment": "Amount does not match the bill"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/approvals/{approval_id}/withdraw": {
      "post": {
        "tags": [
          "approvals"
        ],
        "summary": "Withdraw one's own request",
        "description": "Take back one's own pending request to raise or remove a company's posting approval limit\n(`object_type` `posting_limit`) or to relax the approval policy (`approval_policy`). Four\neyes is about approving: withdrawing relaxes nothing, and the limit or policy in force stays.\nWithout it, a request nobody else may decide (an administrator whose colleagues are not\nadministrators) would wait forever and block every later one (409\n`posting_limit_change_waiting`, `approval_policy_change_waiting`).\n\nThe request becomes `rejected`, decided by the person who asked, with the comment\n`withdrawn` (followed by the body's optional comment) and `withdrawn` true, and is audited\nas `approval.withdrawn`. When her next change of the same kind applies at once (she is alone\nin the organization; for the posting limit also when she lowers it or the policy allows the\nchange), it withdraws her older request the same way, without this call.\n\nRefused with 403 `approval_withdraw_own_only` for anyone but the person who asked (whichever\nkey or session she uses, and whatever its scopes; a second person rejects instead) and for an\nagent; 403 `approval_withdraw_admin_only` for her without the admin scope; 409\n`approval_not_withdrawable` for another kind of request and `approval_decided` when it is no\nlonger pending.",
        "operationId": "withdraw_v1_approvals__approval_id__withdraw_post",
        "parameters": [
          {
            "name": "approval_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Approval request id (`GET /v1/approvals`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Approval Id"
            },
            "description": "Approval request id (`GET /v1/approvals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/Decision"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              },
              "example": {
                "comment": "Asked too early"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/approvers": {
      "get": {
        "tags": [
          "approvals"
        ],
        "summary": "The approver register",
        "description": "Everyone who may approve (or could, before being disabled), ordered by email, with what\nthe administrator declared when giving them the right (who the person is, their relationship\nto the company and firm, confirmed to be a different person), who declared it and when, when\nthe person confirmed that their approvals are recorded in their name, and every change of\ntheir access. For an administrator and an auditor (the `admin` or `audit` scope; 403\notherwise). See ADR-0098.",
        "operationId": "list_approvers_v1_approvers_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ApproverOut"
                  },
                  "title": "Response List Approvers V1 Approvers Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/archive/export": {
      "get": {
        "tags": [
          "documents",
          "audit"
        ],
        "summary": "Download the archive of an entity as a ZIP",
        "description": "Every original, archived output and attachment of the entity's posted invoices, bills and\ncredit notes dated in the range, as a ZIP for an auditor: the files under\n`files/<document number>/`, and a manifest as `manifest.csv` and `manifest.json` with one row\nper file: the document's number (and the vendor's invoice number of a bill), kind, date,\nparty and total; the file's name, SHA-256 and source (`received`, `captured`,\n`archived_output`, `attached`); who stored it and when; and its `integrity` (`ok`, or\n`mismatch` or `unreadable` for a file that is then left out of the ZIP). A posted document\nwithout a file has a row with empty file columns.\n\n`manifest.json` also has `expected_files` and `included_files`: the export is complete when\nit is in the ZIP and they are equal; **a ZIP without `manifest.json` is incomplete** (the\ndownload was cut short).\n\nThe ZIP is streamed, one file at a time. Needs the `audit` scope (the Auditor role) or `admin`.\nThe export is an audit event (`archive.export`) with the entity, the range and the counts.\n404 for an unknown entity, 422 when `end` is before `start`.",
        "operationId": "export_archive_v1_archive_export_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Document date from, inclusive (ISO 8601, `2026-01-01`).",
              "title": "Start"
            },
            "description": "Document date from, inclusive (ISO 8601, `2026-01-01`)."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Document date to, inclusive (ISO 8601, `2026-12-31`).",
              "title": "End"
            },
            "description": "Document date to, inclusive (ISO 8601, `2026-12-31`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "A ZIP with the files and a manifest (`manifest.csv`, `manifest.json`).",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "audit"
            ]
          },
          {
            "apiKeyAuth": [
              "audit"
            ]
          }
        ],
        "x-required-scope": "audit"
      }
    },
    "/v1/assets": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Register a fixed asset",
        "description": "Register an asset; the depreciation schedule comes from data-vNext.\n\nThe yearly schedule of the accounting book is computed from the method, useful life and\nconvention (and from `tax_asset_class` for the older single tax memo, and from `books`\nfor tax books); the response returns it. `post_acquisition` also posts Dr asset cost /\nCr `credit_account` through the approval policy; `acquisition_status` says whether that\nentry is posted or waits for approval. A purchase bill given as `source_document` is\nlinked instead. Accounts default to the entity's asset roles. The `credit_account` follows\nthe rule for the accounts of documents: not a control account (receivables, payables, bank,\nthe asset accounts), not a tax account, neither revenue nor expense; an acquisition paid or\nowed goes to a clearing account. A wrong acquisition is undone with\n`POST /v1/assets/{asset}/reverse-acquisition`. Refused: 409 when the code exists in the\nentity; 422 when the source document is not a purchase bill, the residual value is not\nbelow the cost (`salvage_not_below_cost`), the asset goes into service before it is acquired\n(`in_service_before_acquisition`), `post_acquisition` has no `credit_account`, the credit\naccount is one the rule refuses (`control_account_on_document`, `tax_account_on_document`,\n`document_account_type`), or a tax book needs an asset class or method.",
        "operationId": "register_asset_v1_assets_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssetInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetRegistered"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Get a fixed asset",
        "description": "One asset with its terms, accounts (by code), source bill and the books it is in.\n\nCost and salvage are in the entity's functional currency. Position and schedules per\nbook are in `GET /v1/assets/{asset}/books`. Refused with 404 for an unknown asset.",
        "operationId": "get_asset_v1_assets__asset__get",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/assets/{asset}/books": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "List the books of a fixed asset",
        "description": "Every book the asset is depreciated in, with its schedule and position at ``as_of``.\n\nThe accounting book `BOOK` comes first (accumulated depreciation as posted), then `MEMO`\nwhen the asset has a tax memo, then the tax books by code. For tax books the response\nalso gives the temporary difference against the accounting book and, for the book that\ncarries deferred tax, the deferred tax amount. Refused with 404 for an unknown asset.",
        "operationId": "list_asset_books_v1_assets__asset__books_get",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Position date, ISO 8601 (YYYY-MM-DD). Default: today.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "Position date, ISO 8601 (YYYY-MM-DD). Default: today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AssetBookOut"
                  },
                  "title": "Response List Asset Books V1 Assets  Asset  Books Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Add a fixed asset to a tax book",
        "description": "Depreciate the asset in a tax book too; the schedule comes from data-vNext.\n\nGive an `asset_class` (which fills method, life, rate and convention) or at least a\n`method`; the schedule is computed from the asset's cost and in-service date and\nreturned with the position as of today. Nothing is posted. Refused: 404 for an unknown\nasset or tax book; 409 when the asset is already in the book; 422 when neither\n`asset_class` nor `method` is given or the class is from another jurisdiction than the\nbook's regime.",
        "operationId": "add_asset_book_v1_assets__asset__books_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssetBookInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetBookOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}/books/{book}/schedule": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Get an asset's depreciation schedule in one book",
        "description": "The schedule by fiscal year and the position at ``as_of`` of one of the asset's books.\n\nSame content as one element of `GET /v1/assets/{asset}/books`. Refused with 404 when the\nasset does not exist or is not in that book.",
        "operationId": "asset_book_schedule_v1_assets__asset__books__book__schedule_get",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "book",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Book code: `BOOK` (accounting book), `MEMO` or a tax book such as `TAX-CH`.",
              "examples": [
                "BOOK"
              ],
              "title": "Book"
            },
            "description": "Book code: `BOOK` (accounting book), `MEMO` or a tax book such as `TAX-CH`."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Position date, ISO 8601 (YYYY-MM-DD). Default: today.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "Position date, ISO 8601 (YYYY-MM-DD). Default: today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetBookOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/assets/{asset}/dispose": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Dispose of a fixed asset",
        "description": "Derecognise an active asset on `disposal_date` and book the gain or loss.\n\nPosts one entry dated at the disposal: the depreciation the schedule reaches by the end\nof the disposal period and not yet booked (Dr expense / Cr accumulated; the other way\nround for what runs of later periods of its fiscal year booked after the disposal date),\nCr cost, Dr accumulated depreciation, Dr `proceeds_account` for any proceeds, and the\ndifference as gain or loss on the entity's asset-disposal account. The result is the\nusual submit result with the approval `policy` decision; the asset becomes `disposed`\nonce the entry is posted (and keeps its status if it is rejected). An agent's disposal\nalways waits for a person, whatever the policy says of the amount. Refused: 409 when the\nasset is not active, a depreciation entry or an earlier disposal of it waits for approval,\nits acquisition entry is not posted, depreciation of it is booked in a later fiscal year,\nor the period is closed; 422 when there are proceeds without `proceeds_account`,\n`proceeds_account_not_cash` (`account`) when it is not a bank or cash account (a sale on\ncredit is sold on a sales invoice: `POST /v1/assets/{asset}/sale`), or the disposal is dated\nbefore the asset went into service (`disposal_before_in_service`) or after today where the\ncompany is (`disposal_in_future`).",
        "operationId": "dispose_asset_v1_assets__asset__dispose_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DisposalInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}/history": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Get the history of a fixed asset",
        "description": "Everything that happened to the asset, oldest first, each with its date, amount and\njournal entry: its acquisition (the entry, or the purchase bill the cost came from), each\ndepreciation, any other entry booked to it, its disposal and reversals of these; then each\ntax book's depreciation of the fiscal years that have ended (tax books post nothing). Also\nthe asset's audit trail. `book_value` is the accounting book's value after each posted\nentry. Refused with 404 for an unknown asset.",
        "operationId": "get_asset_history_v1_assets__asset__history_get",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetHistory"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/assets/{asset}/impairment": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Write down a fixed asset (impairment)",
        "description": "Write the carrying amount of an active asset down by `amount`, or to `recoverable_amount`.\n\nPosts one entry dated `impairment_date`: first the depreciation the schedule reaches by the\nend of the period and has not booked yet, then Dr impairment loss (role\n`asset_impairment_loss`) / Cr the asset's accumulated depreciation. An asset carried at a\nrevalued amount sets the write-down against its revaluation surplus first (IAS 36.61). The\nsalvage is at most the new carrying amount; from the next period the lower value is\ndepreciated over the rest of the useful life. The entry goes through the approval policy;\na rejection puts the asset back. Refused as a partial retirement is (409 and 422), and 422\nwhen the write-down is more than the carrying amount (`impairment_too_large`) or the\nrecoverable amount is not below it (`no_impairment`).",
        "operationId": "impair_asset_v1_assets__asset__impairment_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImpairmentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetChangeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}/impairment-reversal": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Reverse an impairment of a fixed asset",
        "description": "Write an impaired asset up again by `amount`, or to `recoverable_amount`, once the reasons\nfor the impairment no longer apply (IAS 36.114; HGB § 253 (5), the Wertaufholung; OR 960a).\n\nPosts one entry dated `reversal_date`: first the depreciation the schedule reaches by the end\nof the period and has not booked yet, then Dr the asset's accumulated depreciation / Cr the\nimpairment account (role `asset_impairment_loss`), as income. The write-up is at most the\nvalue the asset would have, net of depreciation, had it not been impaired, and what its\nimpairments took to profit or loss (IAS 36.117): a `recoverable_amount` above it writes the\nasset up to it, an `amount` above it is refused. The asset stays at cost less depreciation;\nfrom the next period the higher value is depreciated over the rest of the useful life. A\nperson records it (the policy action `change_asset_value`, which agents are always denied:\n403), and the entry goes through the approval policy; a rejection puts the asset back. Refused\nas a partial retirement is (409 and 422), and 409 under US GAAP and ASPE, which forbid it\n(`impairment_reversal_not_allowed` with `law`); 422 when the asset carries no impairment to\nreverse (`no_impairment_to_reverse`), the recoverable amount is not above the carrying amount\n(`no_reversal`) or the amount is above what may be reversed (`impairment_reversal_too_large`\nwith `most`).",
        "operationId": "reverse_impairment_v1_assets__asset__impairment_reversal_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImpairmentReversalInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetChangeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}/partial-retirement": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Retire a part of a fixed asset",
        "description": "Retire a part of an active asset, given as a percentage or an amount of its cost.\n\nPosts one entry dated `retirement_date`: first the depreciation the schedule reaches by the\nend of the period and has not booked yet, then Cr cost of the part, Dr its share of the\naccumulated depreciation, Dr `proceeds_account` for the net proceeds and the difference as\ngain or loss on the asset-disposal accounts. The salvage shrinks in proportion; from the next\nperiod what is left is depreciated over the rest of the useful life. The entry goes through\nthe approval policy (`submit`); while it waits, depreciation runs leave the asset alone, and\na rejection puts the asset back as it was. To sell the part to a customer on an invoice, use\n`POST /v1/assets/{asset}/sale`. Refused: 409 when the asset is not active, something of it\nwaits for approval (`asset_change_waits`, `disposal_waits`, `depreciation_waits`),\ndepreciation is booked after the period (`depreciation_booked_later`), its value changed\nlater (`asset_changed_later`) or the period is closed; 422 for a date before the asset is in\nservice (`asset_change_before_service`) or after today (`asset_change_in_future`), a part not\nbelow the cost (`retirement_too_large`: dispose of the asset instead) or proceeds without\n`proceeds_account`.",
        "operationId": "retire_part_v1_assets__asset__partial_retirement_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartialRetirementInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetChangeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}/revaluation": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Revalue a fixed asset to fair value",
        "description": "Revalue an active asset to `fair_value` under the revaluation model (IAS 16.31).\n\nPosts one entry dated `revaluation_date`: first the depreciation the schedule reaches by the\nend of the period and has not booked yet, then the accumulated depreciation eliminated against\nthe cost and the cost restated to the fair value (IAS 16.35(b)). A rise is credited to the\nrevaluation surplus in equity (role `revaluation_surplus`), as income where it reverses an\nearlier loss of the asset; a fall is set against the asset's surplus first and the rest is a\nloss (IAS 16.39 and 40). From the next period the revalued amount less the salvage is\ndepreciated over the rest of the useful life. The entry goes through the approval policy; a\nrejection puts the asset back. Refused as a partial retirement is (409 and 422), and 409 when\nthe company's books follow a law that keeps assets at cost (`revaluation_not_allowed` with\n`law`: Swiss OR 960a, HGB § 253 (1), art. 2426 c.c., the Spanish PGC, US GAAP, ASPE) or for\na French free revaluation (`revaluation_not_built`); 422 when the fair value is the carrying\namount (`revaluation_no_change`) or the useful life is over (`asset_life_over`, 409).",
        "operationId": "revalue_asset_v1_assets__asset__revaluation_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevaluationInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetChangeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}/reverse-acquisition": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Reverse the acquisition of a fixed asset",
        "description": "Take an asset registered or posted by mistake off the register, reversing its acquisition.\n\nFor an active asset with no depreciation booked and no disposal. Its acquisition entry is\nreversed like a journal entry: dated `on` (default: the acquisition entry's date; its period\nmust be open), with the required `reason`, through the approval policy (action\n`reverse_entry`, source `fa`). Only a person reverses (403 for an agent or without the post\nscope); an acquisition someone else created, posted or approved waits for a second person\n(`status` `pending_approval` with `approval_id`, decided with\n`POST /v1/approvals/{approval_id}/approve`, which checks everything again). Once the\nreversal is posted the asset's status is `reversed`. An asset without an acquisition entry\nof its own (bought with a purchase bill, or already on the books) has nothing to reverse\nand leaves the register at once; correct the bill with a vendor credit note. Refused: 409\nwhen the asset is not active, a disposal of it waits, depreciation of it is booked\n(`asset_depreciated`: dispose of it instead) or its value changed (`asset_value_changed`), its\nacquisition waits for approval or is\nalready reversed (or its reversal waits), or the period is closed; 422 without a reason.",
        "operationId": "reverse_asset_acquisition_v1_assets__asset__reverse_acquisition_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReverseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetReversalResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/assets/{asset}/sale": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Sell a fixed asset to a customer on an invoice",
        "description": "Sell an active asset, or a part of it (`percent` or `cost`), to a customer.\n\nMakes and submits a sales invoice dated `sale_date` to `customer`: one line of goods for\n`net_amount` at the VAT rate `rate_type` (the customer's country decides the treatment, as on\nany invoice), booked to the clearing account of asset sales (role `asset_sale_clearing`), so\nthe VAT is on the VAT return and the receivable on the customer. Then the whole asset is\ndisposed of (as `POST /v1/assets/{asset}/dispose`) or the part retired (as `POST\n/v1/assets/{asset}/partial-retirement`) against the invoice's net amount in the company's\ncurrency (`proceeds`), which the asset's entry takes out of the clearing account: the gain\nor loss is against the proceeds without VAT. Both entries go through the approval policy;\nthe asset's entry posts only after the invoice (`sale_invoice_not_posted`). An agent's sale\nalways waits for a person: the invoice, and then the asset's entry. Refused as the disposal or\nthe partial retirement is, and as the invoice is (an unknown or inactive customer, a closed\nperiod).\n\nA price reduced after the sale is an ordinary sales credit note (`POST /v1/documents`) whose\nline names the account of gains on disposals (role `asset_disposal_gain`). A line on the\naccount of losses on disposals is refused as on any sales document (422\n`document_account_type`: an expense account), and one on the clearing account too (422\n`control_account_on_document`: only the sale's invoice books there).",
        "operationId": "sell_asset_v1_assets__asset__sale_post",
        "parameters": [
          {
            "name": "asset",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Asset code, e.g. `FA-001` (or its id).",
              "examples": [
                "FA-001"
              ],
              "title": "Asset"
            },
            "description": "Asset code, e.g. `FA-001` (or its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssetSaleInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AssetSaleOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/audit-events": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "Audit Events",
        "description": "The audit trail, newest first: who (`actor`) did what (`action`, e.g. `journal.post`)\nto which object, with the request id and idempotency key of the call and event-specific\n`data`. Events are append-only and cannot be changed. Narrow it with `object_type` and\n`object_id`.",
        "operationId": "audit_events_v1_audit_events_get",
        "parameters": [
          {
            "name": "object_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only events about this kind of object, e.g. `journal_entry`, `entity`, `account`, `period`, `api_key`, `app_user`, `organization`.",
              "examples": [
                "journal_entry"
              ],
              "title": "Object Type"
            },
            "description": "Only events about this kind of object, e.g. `journal_entry`, `entity`, `account`, `period`, `api_key`, `app_user`, `organization`."
          },
          {
            "name": "object_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only events about the object with this id (as text, usually a uuid).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Object Id"
            },
            "description": "Only events about the object with this id (as text, usually a uuid)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "description": "How many events to return, newest first; at most 1000.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many events to return, newest first; at most 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AuditEventOut"
                  },
                  "title": "Response Audit Events V1 Audit Events Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/auth/company/finish": {
      "post": {
        "tags": [
          "company sign-in"
        ],
        "summary": "Finish a company sign-in",
        "description": "Exchange the `code` the identity provider sent back for its ID token, check it (signature,\nissuer, audience, expiry, nonce, a verified address of one of the connection's domains) and\nsign the person in to that organization only. The answer is that of `POST /v1/auth/google`:\n`passkey` (then `POST /v1/auth/passkey`). Refused with 403 for a state that is too old or not\nthis server's (`company_sign_in_state`), a token that does not hold\n(`company_sign_in_refused`) or an address that does not fit (`company_sign_in_email`).",
        "operationId": "finish_v1_auth_company_finish_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompanyFinish"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/company/start": {
      "post": {
        "tags": [
          "company sign-in"
        ],
        "summary": "Start a company sign-in",
        "description": "The identity provider's sign-in page for an address whose organization signs in with its\nown provider. It needs no credential and serves the web UI's sign-in page. The browser goes to\n`url` and comes back to the redirect URI with `code` and `state` for\n`POST /v1/auth/company/finish`. Refused with 403 (`company_sign_in_none`) when no organization\nthat invited the address covers its domain.",
        "operationId": "start_v1_auth_company_start_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompanyStart"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyStartOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/config": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "Get the sign-in settings",
        "description": "What the web UI's sign-in page needs: the Google OAuth client id (`google_client_id`,\nnull when Google sign-in is not configured), where people without a Google account sign in\nwith a password (`password_sign_in`, null when not configured) and whether the development\nlogin is on. It needs no credential and is not for API-key clients, which sign in with their\nkey.",
        "operationId": "auth_config_v1_auth_config_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthConfig"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/v1/auth/google": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Sign in with Google",
        "description": "Exchange a Google ID token for a web UI session cookie.\n\nThis endpoint serves the web UI session and is not for API-key clients: a script\nauthenticates with an API key (`Authorization: Bearer <key>`), never with this call. The\ncaller must have been invited (`POST /v1/users`). On success the answer is `passkey`: every\nsign-in also needs the person's passkey (ADR-0101). The browser touches it, or creates the\nfirst one, with the options in `passkey`, and sends the answer to `POST /v1/auth/passkey`,\nwhich sets the `erp_session` cookie (HttpOnly, SameSite=Strict). When the address belongs\nto several organizations the answer is `choose_organization` with the list: repeat the call\nwith the chosen `org_id`. No cookie is set by this call. Refused with 403 for an invalid token,\na person who is not invited, a domain that may not sign in, or an `org_id` that is not\ntheirs; with 422 when Google sign-in is not configured on the server.",
        "operationId": "google_login_v1_auth_google_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GoogleLogin"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          }
        },
        "security": [],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/logout": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Sign out of the web UI",
        "description": "End the web UI session whose cookie accompanies the request and clear the cookie. It\nserves the web UI and is not for API-key clients: with an API key there is no session to\nend and nothing happens. The response has no body.",
        "operationId": "logout_v1_auth_logout_post",
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/organizations": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "List my organizations",
        "description": "The organizations the signed-in person may switch to, their current one included, as\nsign-in lists them (`test_organization` marks a test copy or demo). Only for a web UI session:\nan API key answers 403, as it belongs to one organization.",
        "operationId": "my_organizations_v1_auth_organizations_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/Membership"
                  },
                  "type": "array",
                  "title": "Response My Organizations V1 Auth Organizations Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ]
      }
    },
    "/v1/auth/passkey": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Sign in with a passkey",
        "description": "The second step of every sign-in to the web UI (ADR-0101): the browser's answer to the\n`passkey` question of `POST /v1/auth/google` or `POST /v1/auth/password`. For a person\nwithout a passkey the answer creates their first (`name` names it); otherwise it is a touch\nof one of theirs. On success the answer is `signed_in` and the `erp_session` cookie is set\n(HttpOnly, SameSite=Strict). The question is valid once and for five minutes. Refused with\n403 for an answer that does not verify (`passkey_refused`), a question that is used or\nexpired (`passkey_expired`, sign in again) or a person who may no longer sign in; with 409\nfor a passkey already registered. A passkey made at the site's former address (it moved) is\nanswered `passkey` once more: create the passkey of this address with that question and send\nthe answer here; the session starts with it. Refusals count against the client address like\nrefused sign-ins (429 past the limit). It serves the web UI and is not for API-key clients.",
        "operationId": "passkey_login_v1_auth_passkey_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasskeyAnswer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/password": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Sign in with a password",
        "description": "Exchange the ID token of an e-mail and password sign-in at Google Identity Platform for a\nweb UI session cookie, for people without a Google account (ADR-0037).\n\nThe browser sends the address and password to Google (`accounts:signInWithPassword` with the\n`password_sign_in.api_key` of `GET /v1/auth/config`), never to this server; Google keeps the\npassword and refuses repeated wrong ones. This call takes the `idToken` Google returned. It\nserves the web UI and is not for API-key clients. The answers are those of\n`POST /v1/auth/google`: `passkey` (then `POST /v1/auth/passkey`), or `choose_organization`.\nRefused with 403 for an invalid token, an address that is not verified, a person who is not\ninvited, a domain that may not sign in, or an `org_id` that is not theirs; with 409 when\npassword sign-in is not configured. Failed sign-ins count against the client address (429\npast the limit).",
        "operationId": "password_login_v1_auth_password_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasswordLogin"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/step-up": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Touch your passkey again",
        "description": "Check the browser's answer to `POST /v1/auth/step-up/options` and note the touch on the\nsession: steps that ask for a fresh touch work for five minutes from now. 403 for an answer\nthat does not verify, a used or expired question, another session's question or an API key.",
        "operationId": "step_up_v1_auth_step_up_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasskeyAnswer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StepUpDone"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/step-up/options": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Ask for a fresh passkey touch",
        "description": "The question for a fresh touch of the signed-in person's passkey, which a risky step asks\nfor (403 `passkey_step_up` with `within_minutes`): touch it in the browser with these\noptions, send the answer to `POST /v1/auth/step-up`, then repeat the step. Only for a web UI\nsession (403 for an API key).",
        "operationId": "step_up_options_v1_auth_step_up_options_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasskeyStep"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/auth/switch": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Switch organization",
        "description": "Move the signed-in person to another of their organizations (`GET /v1/auth/organizations`)\nwithout signing in again, for example from a test copy back to the real organization. The\ncurrent session ends and a new one starts in `org_id`, checked as a sign-in with the same\naccount would be: the answer and the `erp_session` cookie are those of `signed_in`. The new\nsession ends when the current one would have: a switch never extends a sign-in. Refused with\n403 for an `org_id` that is not theirs and for an API key, and with 409 for the organization\nthe person is already in. A suspended organization may still be left this way. Recorded as\n`user.login` with `via: switch` and the organization left (`from_org`).",
        "operationId": "switch_organization_v1_auth_switch_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrganizationSwitch"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoginResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/autopilot/passes/{pass_id}": {
      "get": {
        "tags": [
          "autopilot"
        ],
        "summary": "Get an Autopilot pass",
        "description": "What the pass did step by step: what was open, what the rules settled, each item the AI\nworked on with the tools it called and whether the outcome's check found it settled, what it\nasked, and the steps it left a person.",
        "operationId": "get_autopilot_pass_v1_autopilot_passes__pass_id__get",
        "parameters": [
          {
            "name": "pass_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id (uuid) of the pass.",
              "title": "Pass Id"
            },
            "description": "Id (uuid) of the pass."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/autopilot/questions/{question_id}/answer": {
      "post": {
        "tags": [
          "autopilot"
        ],
        "summary": "Answer a question of Autopilot",
        "description": "The answer goes to the AI with the item in the next pass, which comes soon. 409\n`autopilot_question_closed` for a question already answered or dropped. Needs an\n`Idempotency-Key`.",
        "operationId": "answer_autopilot_question_v1_autopilot_questions__question_id__answer_post",
        "parameters": [
          {
            "name": "question_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id (uuid) of the question.",
              "title": "Question Id"
            },
            "description": "Id (uuid) of the question."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnswerInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuestionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/bank-lines/{line_id}/candidates": {
      "get": {
        "tags": [
          "banking"
        ],
        "summary": "List matching documents for a bank line",
        "description": "Open documents and booked payments that could settle the line, scored with reasons.\n\nFor a credit the documents are posted sales invoices and purchase credit notes, for a debit\nposted purchase bills and sales credit notes, in any currency (at most 10): one in another\ncurrency than the line's gives its open amount at the booking day's rate (`line_open`). Each\ngives its open amount, any cash discount available at the booking date and the reasons for\nits score (structured reference, reference text, exact amount, IBAN, counterparty name).\nCandidates of kind `payment` are payments already booked from the line's bank account, in\nits direction, that no bank line settles yet: in the line's currency at the exact amount, or\nin another currency (a line in the functional currency) within 2% of what they booked,\nwith the bank's `difference`; link the line to one with `POST .../link` rather than post it\nto an account, which would book the payment twice. For a credit, candidates of kind\n`return` are outgoing payments of the line's bank account the bank executed and that are\nstill posted, which the line may return (ADR-0062): linking one reverses that payment by the\nline. Best score first. Refused with 409 when the line is no longer unmatched.",
        "operationId": "line_candidates_v1_bank_lines__line_id__candidates_get",
        "parameters": [
          {
            "name": "line_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Line Id"
            },
            "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Candidate"
                  },
                  "title": "Response Line Candidates V1 Bank Lines  Line Id  Candidates Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/bank-lines/{line_id}/ignore": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Ignore a bank line",
        "description": "Mark an unmatched line as ignored, with a reason, so it no longer needs matching.\n\nNothing is posted. Use it for lines that need no booking, for example a transfer that is\nrecorded elsewhere. `POST /v1/bank-lines/{line_id}/reopen` undoes it. Refused with 409\nwhen the line is not unmatched.",
        "operationId": "ignore_line_v1_bank_lines__line_id__ignore_post",
        "parameters": [
          {
            "name": "line_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Line Id"
            },
            "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IgnoreRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankLineOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/bank-lines/{line_id}/link": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Link a bank line to a booked payment",
        "description": "Settle the line by a payment already booked, which it executes (a candidate of kind\n`payment`): nothing is booked again. For a payment in another currency than the line's,\nthe bank's `difference` to what the payment booked (its conversion rate against the ECB\nrate of the payment date) is booked against the bank account as a realised exchange gain\nor loss, through the approval policy (`difference_entry`); a rejected entry returns the line\nto unmatched. The line becomes `matched`. Refused: 409 when the line is not unmatched; 422\nwhen the payment is not a booked payment of the line's bank account and direction that no\nother line settles (`bank_line_payment_not_booked`), or its amount does not fit\n(`bank_line_amount_differs`: a payment in the line's currency fits only at its exact\namount, one in another currency within 2%). The line's own entry is dated `on` (default: the\nbooking date, or when its period is closed the first day of the next open period, the line's\n`posting_date`); the payment stands as booked, in a closed month too.\n\nLinking a credit to an outgoing payment (a candidate of kind `return`) records that the\nmoney came back (ADR-0062): the payment is reversed by the line, the bank account debited by\nwhat came back, and the bills it paid are open again once the reversal is posted (it follows\nthe approval policy and the four-eyes rules; `difference_entry` is the reversal). Refused\n(422) when the payment is not an outgoing payment of the line's bank account that the bank\nexecuted and that is still posted (`bank_line_not_returnable`).",
        "operationId": "link_line_v1_bank_lines__line_id__link_post",
        "parameters": [
          {
            "name": "line_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Line Id"
            },
            "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/bank-lines/{line_id}/match": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Match a bank line to documents",
        "description": "Settle the line against open documents of one party by recording a payment.\n\nThe allocations must add up to the absolute amount of the line; the payment is incoming\nfor a credit and outgoing for a debit, dated `on` (default: the booking date, or when its\nperiod is closed the first day of the next open period, the line's `posting_date`). A\ndocument in another currency than the line's is settled by the allocation's\n`document_amount` (its open amount, when the line pays it in full), the difference booked as\nrealised FX. The payment entry follows the approval policy, so the result can be pending\napproval (`submit.policy`). The line becomes `matched`. Refused: 409 when the line is not\nunmatched or the period of `on` is closed; 422 when the documents belong to different\nparties, the allocations do not add up, a document cannot be settled (wrong kind, not posted,\namount above what is open), or `on` is before the booking date (`bank_posting_before_line`).",
        "operationId": "match_line_v1_bank_lines__line_id__match_post",
        "parameters": [
          {
            "name": "line_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Line Id"
            },
            "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/bank-lines/{line_id}/post": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Post a bank line to an account",
        "description": "Book a line directly against an account (bank fees, interest).\n\nCreates a two-line journal entry dated `on` (default: the booking date, or when its period\nis closed the first day of the next open period, the line's `posting_date`): the bank account\nagainst\n`account`, in the line's currency, and submits it. The response carries the approval\npolicy decision (`policy`: allow, require_approval or deny); the line becomes `matched`\nand returns to unmatched if the entry is rejected. Refused with 409 when the line is not\nunmatched or the period of `on` is closed, with 422 `bank_posting_before_line` when `on` is\nbefore the booking date, with 404 when the counter account does not exist.",
        "operationId": "post_line_v1_bank_lines__line_id__post_post",
        "parameters": [
          {
            "name": "line_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Line Id"
            },
            "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PostLineInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/bank-lines/{line_id}/reopen": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Reopen an ignored bank line",
        "description": "Undo 'ignore': the line is unmatched again (a matched line is undone with\n`POST /v1/bank-lines/{line_id}/unmatch`). Safe to repeat without an Idempotency-Key: a line\nthat is not ignored is refused with 409.",
        "operationId": "reopen_line_v1_bank_lines__line_id__reopen_post",
        "parameters": [
          {
            "name": "line_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Line Id"
            },
            "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankLineOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/bank-lines/{line_id}/unmatch": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Undo the match of a bank line",
        "description": "Undo the match of a matched line, with a `reason` (required, at most 500 characters).\n\nWhat the match did is undone (`outcome`): a line only linked to a payment booked before (a\npayment released in a payment file) is `unlinked` and the payment stands; a payment or\nposting the match made that still waits for approval is `withdrawn` (rejected, nothing was\nposted); a posted payment is `reversed` as `POST /v1/payments/{payment_id}/reverse` does,\nand a posted posting of the line (fees, interest) is `reversed` as a journal entry, dated\n`on` (default: today for a payment, the posting's date for a posting). Each reversal follows\nits approval policy: `pending_approval` means it waits for a second person (`approval_id`)\nand the line stays matched, with `match.undo`, until it is approved. Otherwise the line is\nunmatched again, and the close job's matcher leaves it to a person.\n\nOnly a person undoes a match (403 for an agent). Refused with 409: the line is not matched,\nits undoing already waits for approval, or the period of the date is closed. Safe to repeat\nwithout an Idempotency-Key: a second request is refused with 409.",
        "operationId": "unmatch_line_v1_bank_lines__line_id__unmatch_post",
        "parameters": [
          {
            "name": "line_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Line Id"
            },
            "description": "Bank statement line id (`GET /v1/entities/{entity}/bank-lines`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnmatchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UnmatchResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/capacity-bookings": {
      "get": {
        "tags": [
          "capacity"
        ],
        "summary": "List bookings",
        "description": "The bookings, by first day and number, with their item, customer, days and units.",
        "operationId": "list_capacity_bookings_v1_capacity_bookings_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "item",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this item's (product code, with `entity`, or id).",
              "title": "Item"
            },
            "description": "Only this item's (product code, with `entity`, or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "booked",
                    "cancelled"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only `booked` or `cancelled`.",
              "title": "Status"
            },
            "description": "Only `booked` or `cancelled`."
          },
          {
            "name": "first_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those that cover a day on or after this one.",
              "title": "First Day"
            },
            "description": "Only those that cover a day on or after this one."
          },
          {
            "name": "last_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those that cover a day on or before this one.",
              "title": "Last Day"
            },
            "description": "Only those that cover a day on or before this one."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 5000,
              "minimum": 1,
              "description": "How many, by first day and number.",
              "default": 500,
              "title": "Limit"
            },
            "description": "How many, by first day and number."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BookingOut"
                  },
                  "title": "Response List Capacity Bookings V1 Capacity Bookings Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "capacity"
        ],
        "summary": "Book capacity",
        "description": "Book units of an item in every slot from the first to the last day (both included), for a\ncustomer or none named. 409 (`capacity_full`, with the first day short) when a day has fewer\nunits free than asked for. Nothing is posted. Needs an `Idempotency-Key`.",
        "operationId": "create_capacity_booking_v1_capacity_bookings_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/capacity-bookings/{booking_id}": {
      "get": {
        "tags": [
          "capacity"
        ],
        "summary": "Get a booking",
        "description": "The booking with its item, customer, days and units.",
        "operationId": "get_capacity_booking_v1_capacity_bookings__booking_id__get",
        "parameters": [
          {
            "name": "booking_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the booking.",
              "title": "Booking Id"
            },
            "description": "Id of the booking."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/capacity-bookings/{booking_id}/cancel": {
      "post": {
        "tags": [
          "capacity"
        ],
        "summary": "Cancel a booking",
        "description": "Free its units. 409 (`booking_cancelled`) when it is cancelled already, and\n(`booking_held`) when a module keeps it (a hotel stay's rooms are cancelled with the stay).",
        "operationId": "cancel_capacity_booking_v1_capacity_bookings__booking_id__cancel_post",
        "parameters": [
          {
            "name": "booking_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the booking.",
              "title": "Booking Id"
            },
            "description": "Id of the booking."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookingOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/capacity-items": {
      "get": {
        "tags": [
          "capacity"
        ],
        "summary": "List capacity items",
        "description": "The products sold by the time slot, by entity and code: the slot, the units in each slot\nand what is booked and free today.",
        "operationId": "list_capacity_items_v1_capacity_items_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CapacityItemOut"
                  },
                  "title": "Response List Capacity Items V1 Capacity Items Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "capacity"
        ],
        "summary": "Sell a product by the time slot",
        "description": "Make a product sold per unit that is not goods (a room, a seat, people's time) bookable:\nits slot (`night`, `day` or `hour`, never changed) and how many units it has in each. 409\nwhen it is already. Nothing is posted. Needs an `Idempotency-Key`.",
        "operationId": "create_capacity_item_v1_capacity_items_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CapacityItemInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CapacityItemOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/capacity-items/{product_id}": {
      "get": {
        "tags": [
          "capacity"
        ],
        "summary": "Get a capacity item",
        "description": "The item with its slot, units and what is booked and free today.",
        "operationId": "get_capacity_item_v1_capacity_items__product_id__get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the capacity item's product (`GET /v1/capacity-items`).",
              "title": "Product Id"
            },
            "description": "Id of the capacity item's product (`GET /v1/capacity-items`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CapacityItemOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "capacity"
        ],
        "summary": "Change a capacity item's units",
        "description": "Set how many units it has in each slot. 409 (`capacity_booked`) when fewer than are\nbooked on a day from today on. Audited with the previous units.",
        "operationId": "update_capacity_item_v1_capacity_items__product_id__patch",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the capacity item's product (`GET /v1/capacity-items`).",
              "title": "Product Id"
            },
            "description": "Id of the capacity item's product (`GET /v1/capacity-items`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CapacityItemUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CapacityItemOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/capacity-items/{product_id}/availability": {
      "get": {
        "tags": [
          "capacity"
        ],
        "summary": "What is free on each day",
        "description": "The units, the units booked and the units free on each day (for a night: the night that\nstarts that day), at most a year at a time.",
        "operationId": "capacity_availability_v1_capacity_items__product_id__availability_get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the capacity item's product (`GET /v1/capacity-items`).",
              "title": "Product Id"
            },
            "description": "Id of the capacity item's product (`GET /v1/capacity-items`)."
          },
          {
            "name": "first_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "From this day; default today.",
              "title": "First Day"
            },
            "description": "From this day; default today."
          },
          {
            "name": "last_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "To this day, included; default 13 days after the first.",
              "title": "Last Day"
            },
            "description": "To this day, included; default 13 days after the first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/charts": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "List chart templates",
        "description": "The chart-of-accounts templates a new entity can start from: `id` is the value of\n`chart` in `POST /v1/entities` (e.g. `ch_kmu`, the Swiss KMU chart; `ifrs_generic`) and\n`countries` those whose standard chart it is (marked `standard` for `country`; provisioning\nstarts an entity from it). `POST /v1/entities` without `chart` uses `ifrs_generic`.",
        "operationId": "charts_v1_charts_get",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^[A-Z]{2}$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "ISO country code.",
              "title": "Country"
            },
            "description": "ISO country code."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChartTemplate"
                  },
                  "title": "Response Charts V1 Charts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/close-tasks/{task_id}": {
      "patch": {
        "tags": [
          "close tracker"
        ],
        "summary": "Change a close task",
        "description": "Change a task's title, owner, working day or check, or take it out of the close\n(`active: false`; a task is never deleted, so the periods it was done for keep it). Omitted\nfields keep their value. **A person's** act (`manage_close`). 404 when it does not exist.",
        "operationId": "update_close_task_v1_close_tasks__task_id__patch",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the close task (`GET /v1/entities/{entity}/close-tasks`).",
              "examples": [
                "8e3f4051-6273-4c84-9d95-afb6c7d8e920"
              ],
              "title": "Task Id"
            },
            "description": "Id of the close task (`GET /v1/entities/{entity}/close-tasks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/company-sign-in": {
      "get": {
        "tags": [
          "company sign-in"
        ],
        "summary": "Get the company sign-in",
        "description": "Whether company sign-in can be set up here, the redirect URI to register at the identity\nprovider, and the organization's connection (its secret is never shown).",
        "operationId": "get_company_sign_in_v1_company_sign_in_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanySignInSetup"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "put": {
        "tags": [
          "company sign-in"
        ],
        "summary": "Set up the company sign-in",
        "description": "Connect the organization's identity provider, or change the connection: the provider, its\nissuer (an Okta domain, an Entra tenant or an issuer URL), the app's client id and secret, the\ne-mail domains whose people sign in through it and whether they may sign in only through it.\nThe provider's discovery document is read first: refused with 502\n(`company_sign_in_unreachable`) when it does not answer for the issuer. Making it the only way\nin (`required`) is refused (`company_sign_in_untried`, 409) until somebody signed in through\nit. Every sign-in through it still ends with the person's passkey.",
        "operationId": "put_company_sign_in_v1_company_sign_in_put",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectionInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "company sign-in"
        ],
        "summary": "Remove the company sign-in",
        "description": "Remove the connection and its sealed secret: its people sign in with Google or a password\nagain.",
        "operationId": "delete_company_sign_in_v1_company_sign_in_delete",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/connectors/authorization": {
      "get": {
        "tags": [
          "organization"
        ],
        "summary": "Check an app's request to connect",
        "description": "What the connect page (`/app/connect`) shows before the person allows an app such as\nClaude's custom connector: the app's name, the host it returns to, the organization it would\nwork in (the person's own) and what it may do. Refused with 422 (`connector_unknown_app`,\n`connector_redirect_not_allowed`) for a request that does not come from an app registered with\nthis server or would return elsewhere than its own address.",
        "operationId": "check_authorization_v1_connectors_authorization_get",
        "parameters": [
          {
            "name": "client_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 4000,
              "description": "The app's client id.",
              "title": "Client Id"
            },
            "description": "The app's client id."
          },
          {
            "name": "redirect_uri",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 2000,
              "description": "Where the app wants the answer.",
              "title": "Redirect Uri"
            },
            "description": "Where the app wants the answer."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectorRequest"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "organization"
        ],
        "summary": "Allow or refuse an app",
        "description": "The person's answer to an app's request to connect (OAuth 2.1 authorization code with\nPKCE, ADR-0082). Allowed, the app gets an **agent key** of this organization bound to the\nperson: `read` and `draft`, with `post` when `post` is true and the person may post, never\n`approve` or `admin`, so everything it prepares still waits for a person and it can never be\nthe second person on what this person started. The key waits for the app to exchange the\none-time code in `redirect_to` within ten minutes, then appears among the API keys, where it\nis revoked. Only a person signed in to the web UI may answer (403 `connector_needs_session`\nfor an API key); 422 for a request that is not an app's of this server\n(`connector_unknown_app`, `connector_redirect_not_allowed`) or not made with PKCE S256\n(`connector_request_invalid`). Recorded as `api_key.create` with `connected_app`.",
        "operationId": "decide_authorization_v1_connectors_authorization_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectorDecision"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectorAnswer"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/consolidation-groups": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "List the consolidation groups",
        "description": "The organization's groups by code, each with the latest approved version of every\nsubsidiary, the member versions that wait for a second person and how many runs it has.",
        "operationId": "list_groups_v1_consolidation_groups_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "At most this many rows.",
              "examples": [
                100
              ],
              "default": 100,
              "title": "Limit"
            },
            "description": "At most this many rows."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/GroupOut"
                  },
                  "title": "Response List Groups V1 Consolidation Groups Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "consolidation"
        ],
        "summary": "Create a consolidation group",
        "description": "Create a group: a parent entity, the reporting currency and the framework (`ifrs`, `fer` or\n`hgb`). A human does it (the policy action `approve_group_structure` denies agents with 403\n`policy_denied`). The reporting currency is the parent's functional currency in this version.\nThe goodwill policy and the useful life of goodwill must be ones the framework allows; a life\nleft empty is the framework's for goodwill whose life cannot be determined (5 years under\n`fer`, 10 under `hgb`). The group has no subsidiary until a member version is\nrequested (`POST /v1/consolidation-groups/{group}/members`) and approved by a second person.\n409 when the code is taken. Needs an `Idempotency-Key`.",
        "operationId": "create_group_v1_consolidation_groups_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GroupInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/consolidation-groups/{group}": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get a consolidation group",
        "description": "One group: the framework (and whether its sources are verified, so that a run is allowed),\nthe latest approved version of every subsidiary and the versions that wait for approval. 404\nfor an unknown group.",
        "operationId": "get_group_v1_consolidation_groups__group__get",
        "parameters": [
          {
            "name": "group",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`).",
              "examples": [
                "DEMO"
              ],
              "title": "Group"
            },
            "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-groups/{group}/checklist": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get the close checklist of a group",
        "description": "The group close checklist at a month end, in the shape of an entity's checklist (`pass`,\n`warn`, `fail`, `n/a`): the member periods are closed, every intercompany relationship between\ntwo members agrees, and, from the latest run at the date, every rate is available, every\naccount maps, every elimination agrees within the tolerance, the translation reserve ties and\nthe balance sheet balances. A run older than the books is a warning on `run`. The checks of\nlater versions (manual adjustments, finalising, non-controlling interests) are `n/a`. `ready`\nis true when nothing fails. 422 when the date is not a month end.",
        "operationId": "get_checklist_v1_consolidation_groups__group__checklist_get",
        "parameters": [
          {
            "name": "group",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`).",
              "examples": [
                "DEMO"
              ],
              "title": "Group"
            },
            "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The group date: a month end (`YYYY-MM-DD`).",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The group date: a month end (`YYYY-MM-DD`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupChecklist"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-groups/{group}/members": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "List the member versions of a group",
        "description": "Every approved version of every subsidiary, by entity and version: who requested and who\napproved it, the share, the control basis and the dates. Versions are append-only; a change is\na new version.",
        "operationId": "list_members_v1_consolidation_groups__group__members_get",
        "parameters": [
          {
            "name": "group",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`).",
              "examples": [
                "DEMO"
              ],
              "title": "Group"
            },
            "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MemberOut"
                  },
                  "title": "Response List Members V1 Consolidation Groups  Group  Members Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "consolidation"
        ],
        "summary": "Request a subsidiary's place in the group",
        "description": "Ask for a new version of a subsidiary in the group: its ownership share, the control\nassessment (IFRS 10.5 to 10.7, Art. 963 para. 2 OR), when it was acquired and from when it is\nconsolidated. A human does it (the policy action `approve_group_structure` denies agents with\n403 `policy_denied`); by default the version waits for a second person (`POST\n/v1/approvals/{approval_id}/approve`, `status: pending_approval`), and a one-person\norganization allows `approve_group_structure` in its approval policy (`PUT\n/v1/approval-policy`), which puts the version in force at once (`status: approved`). A key the\nsystem issued can only request. 409 `rate_source_missing` when the subsidiary's currency is not\npublished by the rate source (the ECB), 409 `fx_rate_missing` when no rate is published yet\nfor the date, 409 when a version of the subsidiary already waits for\napproval, 422 for the parent or a share beyond 100 %. Only direct subsidiaries are supported.\nNeeds an `Idempotency-Key`.",
        "operationId": "request_member_v1_consolidation_groups__group__members_post",
        "parameters": [
          {
            "name": "group",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`).",
              "examples": [
                "DEMO"
              ],
              "title": "Group"
            },
            "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MemberInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MemberResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/consolidation-groups/{group}/runs": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "List the runs of a group",
        "description": "The group's runs, newest date and version first, each with its status and how many blocking\nexceptions and warnings it has.",
        "operationId": "list_runs_v1_consolidation_groups__group__runs_get",
        "parameters": [
          {
            "name": "group",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`).",
              "examples": [
                "DEMO"
              ],
              "title": "Group"
            },
            "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "At most this many rows.",
              "examples": [
                100
              ],
              "default": 100,
              "title": "Limit"
            },
            "description": "At most this many rows."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ConsolidationRunSummary"
                  },
                  "title": "Response List Runs V1 Consolidation Groups  Group  Runs Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "consolidation"
        ],
        "summary": "Run a consolidation",
        "description": "Make a draft run at a month end: read each entity's ledger by entry date (posted entries,\nwithout the year-end closing entries), translate the subsidiaries to the reporting currency at\nthe closing, average and historical rates of data-vNext (IAS 21.39 to 21.41), aggregate by\nreport line, **eliminate intragroup balances (E1), loans (E2), income and expense (E3) and\ndividends (E6)** between the entities, set the investment against the subsidiary's equity at\nacquisition with goodwill and non-controlling interests (E4, E5) and amortise goodwill where\nthe framework's policy does (E7), and keep the snapshot. It is one transaction and it never\nedits an earlier run. Two sides that do not agree in the\ndocument currency are the exception `ic_difference` (blocking above the group's\n`ic_tolerance_amount`). A missing rate is the blocking exception `rate_missing` (the entity is\nleft out and the run says so), never an invented rate. 422 `framework_unverified` or\n`framework_not_implemented` for a framework whose rules are not checked or not built, 422\nwhen the date is not a month end, 409 `no_members` when no subsidiary is consolidated by the\ndate, and 502 when data-vNext is unavailable. Needs an `Idempotency-Key`.",
        "operationId": "create_run_v1_consolidation_groups__group__runs_post",
        "parameters": [
          {
            "name": "group",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`).",
              "examples": [
                "DEMO"
              ],
              "title": "Group"
            },
            "description": "Code or id of the consolidation group (`GET /v1/consolidation-groups`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get a consolidation run",
        "description": "The header of a run: the group date, the framework and its resolved switches (fixed when the\nrun was made), the entities and member versions used, whether it is complete, the digest of its\ninputs and the position of each entity's ledger chain. 404 for an unknown run.",
        "operationId": "get_run_v1_consolidation_runs__consolidation_run__get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/balance-sheet": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get the group balance sheet of a run",
        "description": "The group balance sheet by report line from the run's snapshot (never recomputed from the\nledger): assets, liabilities and equity (capital, retained earnings, the results of earlier\nyears not yet appropriated, the translation reserve) and the result of the year. `balanced`\nsays assets equal liabilities plus equity. Intragroup balances, income and expense are\neliminated (`eliminations_applied`; a run made before the eliminations existed is the aggregate\nof the entities); `complete` is false while the run has a blocking exception.",
        "operationId": "get_balance_sheet_v1_consolidation_runs__consolidation_run__balance_sheet_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupBalanceSheet"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/cash-flow": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get the group cash flow statement of a run",
        "description": "The group cash flow statement of the group year (1 January to the run's date) by the\nindirect method, from the run and the group's run at the end of the previous year (both\nsnapshots): the group's profit, depreciation added back, the change of each report line in\noperating, investing or financing activities, and the effect of exchange rates on the cash of\nsubsidiaries in other currencies; the rest of the translation reserve's movement is its own\noperating line. Each line lists its report lines. 409 `group_opening_run_missing` (`as_of`)\nwhen the entities had books before the year and the group has no run at the end of the\nprevious year; a group whose books start in the year starts from nothing.",
        "operationId": "get_cash_flow_v1_consolidation_runs__consolidation_run__cash_flow_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupCashFlow"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/cta": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get the translation reserve roll-forward of a run",
        "description": "For each translated subsidiary the translation reserve at the group date twice: as the\nbalancing amount of its translated balance sheet, and as the roll-forward of the rates (opening\nnet assets, each month's profit and each equity movement times the move of the closing rate\nsince then, IAS 21.41). They agree within rounding (`reconciled`); a difference beyond it is\nthe blocking exception `cta_unreconciled`. The reserve starts at zero at the date the\nsubsidiary is consolidated from.",
        "operationId": "get_cta_v1_consolidation_runs__consolidation_run__cta_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CtaRollForward"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/eliminations": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "List the eliminations of a run",
        "description": "The elimination layer of the run, per rule and pair of entities: what each side held in\nevery document currency, whether they agree, every line that reverses an account (at the\nclosing rate for a balance, at each month's average for income and expense) and where the\nresidual went. `E1` (intragroup balances): an agreed residual is an exchange difference that\nstays in profit or loss (IAS 21.45). `E3` (intragroup income and expense): an agreed residual is\na translation difference and goes to the translation reserve (IAS 21.41). Sides that disagree\nkeep their residual on a line of its own (`unreconciled`) and the run carries `ic_difference`.\nEvery pair balances. A run made before the eliminations has none (`rules` is empty).",
        "operationId": "get_eliminations_v1_consolidation_runs__consolidation_run__eliminations_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunEliminations"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/exceptions": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "List the exceptions of a run",
        "description": "What the run could not do or the reader should know, blocking first: `rate_missing`,\n`unmapped_report_line`, `cta_unreconciled`, `ic_capitalised` (blocking), `ic_difference`\n(blocking above the group's tolerance, else a warning), `period_open`,\n`member_not_consolidated`, `cta_starts_at_zero` and `ic_exchange_difference` (warnings), and\n`eliminations_pending` (blocking while a subsidiary is in the group, else a warning).",
        "operationId": "get_exceptions_v1_consolidation_runs__consolidation_run__exceptions_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunExceptions"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/profit-and-loss": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get the group profit and loss of a run",
        "description": "The group profit and loss of the group year (1 January to the run's date) by report line\nfrom the snapshot: each month translated at that month's average rate, so it is not one rate\nfor the year. `net_income` equals the result of the year on the balance sheet. Intragroup income\nand expense are eliminated (`eliminations_applied`).",
        "operationId": "get_profit_and_loss_v1_consolidation_runs__consolidation_run__profit_and_loss_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GroupProfitAndLoss"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/rates": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "List the rates a run used",
        "description": "Every rate the run used: closing, average, historical and the rates of equity-movement\ndates, each with its source (the ECB reference rates), its fixing dates and the data-vNext\ndataset version, so the run can be checked later against the same pinned data. No rate is\ninvented and no manual rate is accepted.",
        "operationId": "get_rates_v1_consolidation_runs__consolidation_run__rates_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunRates"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/consolidation-runs/{consolidation_run}/trial-balance": {
      "get": {
        "tags": [
          "consolidation"
        ],
        "summary": "Get an entity's translated trial balance",
        "description": "The translated trial balance of one entity of the run, by account: the amount that was\ntranslated in the entity's functional currency, the amount in the reporting currency and the\nrate. Assets and liabilities are at the closing rate, the group year's income and expenses at\neach month's average rate, equity at the historical rate, the results of earlier years are one\nline and the translation reserve is the balancing amount. The reporting-currency debits equal\nthe credits. 404 when the entity is not part of the run.",
        "operationId": "get_trial_balance_v1_consolidation_runs__consolidation_run__trial_balance_get",
        "parameters": [
          {
            "name": "consolidation_run",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Consolidation Run"
            },
            "description": "Id of the consolidation run (`GET /v1/consolidation-groups/{group}/runs`)."
          },
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code of the entity of the run (`GET /v1/consolidation-runs/{id}` lists them).",
              "examples": [
                "DE01"
              ],
              "title": "Entity"
            },
            "description": "Code of the entity of the run (`GET /v1/consolidation-runs/{id}` lists them)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TranslatedTrialBalance"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/contacts": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List contacts",
        "description": "The people at customers and vendors, by last and first name. Someone who sees only their\nown or their team's records gets the contacts of those people and of the customers they see\n(and every vendor's). Read-only.",
        "operationId": "list_contacts_v1_contacts_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's contacts (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this company's contacts (code or id)."
          },
          {
            "name": "party_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the people at this customer or vendor.",
              "title": "Party Id"
            },
            "description": "Only the people at this customer or vendor."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the name, e-mail or role.",
              "title": "Q"
            },
            "description": "Text in the name, e-mail or role."
          },
          {
            "name": "email",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this e-mail address (any case).",
              "title": "Email"
            },
            "description": "Only this e-mail address (any case)."
          },
          {
            "name": "erased",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Also the erased contacts.",
              "default": false,
              "title": "Erased"
            },
            "description": "Also the erased contacts."
          },
          {
            "name": "owner_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those this person looks after (`GET /v1/people`).",
              "title": "Owner User Id"
            },
            "description": "Only those this person looks after (`GET /v1/people`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, by last and first name.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many, by last and first name."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ContactOut"
                  },
                  "title": "Response List Contacts V1 Contacts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Add a contact",
        "description": "A person at a customer or vendor (`party`): name, role, e-mail, phones, the language to\nwrite to them in, whether they want sales e-mails, and the organization's own contact fields\n(`custom`). An agent may add one. 404 for an unknown company or party; 422 for a field that\nis not one of the organization's or a value of the wrong type. Needs an `Idempotency-Key`.",
        "operationId": "create_contact_v1_contacts_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/contacts/{contact_id}": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get a contact",
        "description": "One contact; an erased one shows only that it existed.",
        "operationId": "get_contact_v1_contacts__contact_id__get",
        "parameters": [
          {
            "name": "contact_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the contact (`GET /v1/contacts`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Contact Id"
            },
            "description": "Id of the contact (`GET /v1/contacts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "crm"
        ],
        "summary": "Change a contact",
        "description": "Change what the request names (`\"\"` clears a text field but the last name; `custom`\nchanges only the keys sent). A contact never moves to another customer or vendor. The audit\ntrail records which fields changed, never their values. 409 `contact_erased` for an erased\none.",
        "operationId": "update_contact_v1_contacts__contact_id__patch",
        "parameters": [
          {
            "name": "contact_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the contact (`GET /v1/contacts`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Contact Id"
            },
            "description": "Id of the contact (`GET /v1/contacts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/contacts/{contact_id}/erase": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Erase a contact's personal data",
        "description": "Empty the contact's name, role, e-mail, phones, and own fields for good (the\nperson asked to be forgotten, or the relationship ended). The row stays, so that the deals and\nactivities that named it still say someone was there; it cannot be undone. A person's\ndecision: 403 `contact_erase_agent` for an agent. 409 `contact_erased` if already erased.",
        "operationId": "erase_contact_v1_contacts__contact_id__erase_post",
        "parameters": [
          {
            "name": "contact_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the contact (`GET /v1/contacts`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Contact Id"
            },
            "description": "Id of the contact (`GET /v1/contacts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/contacts/{contact_id}/merge": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Merge a duplicate contact",
        "description": "Merge this contact, entered twice, into `into`, another contact of the same customer or\nvendor (ADR-0089): what the one that stays has no value for (first name, role, e-mail,\nphones, language, own fields) comes from this one, a \"no sales e-mails\" wish stays, its deals\nand activities move, and this one is erased (`merged_into_id` says where it went). Returns\nthe contact that stays. A person's decision: 403 `merge_agent` for an agent. 422\n`contact_merge_other_party` for a contact of another customer or vendor, or itself; 409\n`contact_erased` if either was erased.",
        "operationId": "merge_contact_v1_contacts__contact_id__merge_post",
        "parameters": [
          {
            "name": "contact_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the contact (`GET /v1/contacts`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Contact Id"
            },
            "description": "Id of the contact (`GET /v1/contacts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactMerge"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContactOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/custom-fields": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List the organization's own fields",
        "description": "The fields the organization added to its companies (customers and vendors), contacts and\ndeals, in their order. A record's values are in its `custom`, by the field's `key`.",
        "operationId": "list_custom_fields_v1_custom_fields_get",
        "parameters": [
          {
            "name": "record",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "company",
                    "contact",
                    "deal"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the fields of `company`, `contact` or `deal` records.",
              "title": "Record"
            },
            "description": "Only the fields of `company`, `contact` or `deal` records."
          },
          {
            "name": "retired",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Also the retired fields.",
              "default": false,
              "title": "Retired"
            },
            "description": "Also the retired fields."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CustomFieldOut"
                  },
                  "title": "Response List Custom Fields V1 Custom Fields Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Add a field of the organization's own",
        "description": "A field on every company, contact or deal: `text`, `number`, `date`, `yes_no` or `choice`\n(with its choices). Its key and type never change. Up to 25 in use per kind of record (409\n`custom_fields_full`); 409 `custom_field_exists` for a key in use. Needs an\n`Idempotency-Key`.",
        "operationId": "create_custom_field_v1_custom_fields_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomFieldInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/custom-fields/{field_id}": {
      "patch": {
        "tags": [
          "crm"
        ],
        "summary": "Change or retire a field of the organization's own",
        "description": "A new label, position or choices (a choice a record holds stays: 409\n`custom_field_choice_in_use`), or `retired`: a retired field leaves the forms and takes no\nnew values; the values records hold stay readable. A field is never deleted.",
        "operationId": "update_custom_field_v1_custom_fields__field_id__patch",
        "parameters": [
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the field (`GET /v1/custom-fields`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Field Id"
            },
            "description": "Id of the field (`GET /v1/custom-fields`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomFieldUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomFieldOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/delivery-notes": {
      "get": {
        "tags": [
          "delivery notes"
        ],
        "summary": "List delivery notes",
        "description": "Delivery notes, newest delivery first, with their lines, cost and what is left to\ninvoice.",
        "operationId": "list_delivery_notes_v1_delivery_notes_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "cancelled",
                    "draft",
                    "pending_approval",
                    "posted"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only notes of this status.",
              "title": "Status"
            },
            "description": "Only notes of this status."
          },
          {
            "name": "customer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Customer code or id (needs `entity`).",
              "title": "Customer"
            },
            "description": "Customer code or id (needs `entity`)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 100
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the number, reference or customer.",
              "title": "Q"
            },
            "description": "Text in the number, reference or customer."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Delivered on or after this day.",
              "title": "Start"
            },
            "description": "Delivered on or after this day."
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Delivered on or before this day.",
              "title": "End"
            },
            "description": "Delivered on or before this day."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, newest first; at most 1000.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many, newest first; at most 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DeliveryNoteOut"
                  },
                  "title": "Response List Delivery Notes V1 Delivery Notes Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Create a delivery note",
        "description": "A draft delivery note of stock items to a customer, from a warehouse (default the\ndefault one), each line optionally for a sales order line. Nothing moves until it is posted.\n422 for a line of an order beyond what is left to ship. Needs an `Idempotency-Key`.",
        "operationId": "create_delivery_note_v1_delivery_notes_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeliveryNoteInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryNoteOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/delivery-notes/{note}": {
      "get": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Read a delivery note",
        "description": "A delivery note with its lines: the cost each line's goods left with, what was invoiced,\nwhat came back and what is left to invoice. The ETag names its version.",
        "operationId": "get_delivery_note_v1_delivery_notes__note__get",
        "parameters": [
          {
            "name": "note",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`.",
              "examples": [
                "DN-2026-000001"
              ],
              "title": "Note"
            },
            "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryNoteOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Change a delivery note",
        "description": "Change a draft (`lines` replaces every line). 409 for a note that is not a draft; 412 when\n`If-Match` names an older version.",
        "operationId": "update_delivery_note_v1_delivery_notes__note__patch",
        "parameters": [
          {
            "name": "note",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`.",
              "examples": [
                "DN-2026-000001"
              ],
              "title": "Note"
            },
            "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed note answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed note answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeliveryNoteUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryNoteOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/delivery-notes/{note}/cancel": {
      "post": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Cancel a delivery note",
        "description": "Cancel a draft: it stays, moves nothing and no longer counts against its order. 409 for a\nnote that is not a draft (a posted note is corrected with a credit note that takes the goods\nback, or a stock adjustment).",
        "operationId": "cancel_delivery_note_v1_delivery_notes__note__cancel_post",
        "parameters": [
          {
            "name": "note",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`.",
              "examples": [
                "DN-2026-000001"
              ],
              "title": "Note"
            },
            "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryNoteOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/delivery-notes/{note}/invoice": {
      "post": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Invoice a delivery note",
        "description": "Draft the sales invoice of what a posted note delivered and is not yet invoiced. Each\ninvoice line names its delivery note line (so the invoice moves no stock) and its sales\norder line, at the order's price; a line without an order takes the product's list price in\nthe customer's currency. Answers the draft invoice, to be checked, posted and sent like any\nother. 409 for a note that is not posted or has nothing left to invoice; 422 when a product\nhas no price. Needs an `Idempotency-Key`.",
        "operationId": "invoice_delivery_note_v1_delivery_notes__note__invoice_post",
        "parameters": [
          {
            "name": "note",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`.",
              "examples": [
                "DN-2026-000001"
              ],
              "title": "Note"
            },
            "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeliveryInvoiceInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/delivery-notes/{note}/pdf": {
      "get": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Download a delivery note",
        "description": "The delivery note as a PDF: the company's letterhead, the customer's address, the\nwarehouse the goods left, the items and quantities, no prices. 409 for a draft or a cancelled\nnote.",
        "operationId": "get_delivery_note_pdf_v1_delivery_notes__note__pdf_get",
        "parameters": [
          {
            "name": "note",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`.",
              "examples": [
                "DN-2026-000001"
              ],
              "title": "Note"
            },
            "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` sends the file as an attachment; `false` inline.",
              "default": false,
              "title": "Download"
            },
            "description": "`true` sends the file as an attachment; `false` inline."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "it",
                    "sv"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`de`, `fr`, `it`, `en` or `sv`; default the customer's.",
              "title": "Language"
            },
            "description": "`de`, `fr`, `it`, `en` or `sv`; default the customer's."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/delivery-notes/{note}/post": {
      "post": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Post a delivery note",
        "description": "Number the draft (`DN-2026-000001`) and issue its goods on the delivery date: Dr cost of\ngoods sold / Cr inventory at moving average. The note is `posted` with each line's cost, or\n`pending_approval` while its stock posting waits for a person. 409 when the warehouse does not\nhold the goods on that day or a later one already booked, or for a note that is not a draft;\n422 for a delivery date after today.",
        "operationId": "post_delivery_note_v1_delivery_notes__note__post_post",
        "parameters": [
          {
            "name": "note",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`.",
              "examples": [
                "DN-2026-000001"
              ],
              "title": "Note"
            },
            "description": "Delivery note id (uuid) or number, e.g. `DN-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryNoteOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/dimensions": {
      "get": {
        "tags": [
          "dimensions"
        ],
        "summary": "List dimensions",
        "description": "What the organization analyses its postings by (every organization starts with\n`cost_centre`, `profit_centre` and `project`), each with its values and the accounts that\nrequire it. A journal line or a document line names values as `dimensions`:\n`{\"cost_centre\": \"CC-100\", \"project\": \"P-17\"}`.",
        "operationId": "list_dimensions_v1_dimensions_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DimensionOut"
                  },
                  "title": "Response List Dimensions V1 Dimensions Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "dimensions"
        ],
        "summary": "Add a dimension",
        "description": "Add a dimension, up to five per organization. Refused with 409 `dimension_exists` for a\ncode that is taken and `dimension_limit` (`max`) beyond five. Audited as\n`dimension.create`. Every change of dimensions, values and required accounts is refused with\n403 when the approval policy denies the action `manage_accounts` (always for agents).",
        "operationId": "create_dimension_v1_dimensions_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DimensionInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/dimensions/{code}": {
      "patch": {
        "tags": [
          "dimensions"
        ],
        "summary": "Change a dimension",
        "description": "Rename a dimension or deactivate it: lines posted with it keep it, new lines may not name\nit. The code never changes. Audited as `dimension.update` with the previous values.",
        "operationId": "update_dimension_v1_dimensions__code__patch",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dimension's code, e.g. `cost_centre`.",
              "examples": [
                "cost_centre"
              ],
              "title": "Code"
            },
            "description": "The dimension's code, e.g. `cost_centre`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DimensionUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/dimensions/{code}/required-accounts": {
      "put": {
        "tags": [
          "dimensions"
        ],
        "summary": "Set the accounts that require a dimension",
        "description": "Replace the accounts of one company on which a manual entry, or a document when it is\nsubmitted, must give the dimension (422 `dimension_required` otherwise). Entries made by the\nsystem (depreciation, revaluation, bank and payment postings) are never refused for lacking\nit. Postings made before are not touched. Audited as `account_dimension_rule.set` with the\nprevious and new accounts.",
        "operationId": "set_required_accounts_v1_dimensions__code__required_accounts_put",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dimension's code, e.g. `cost_centre`.",
              "examples": [
                "cost_centre"
              ],
              "title": "Code"
            },
            "description": "The dimension's code, e.g. `cost_centre`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RequiredAccountsInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/dimensions/{code}/values": {
      "post": {
        "tags": [
          "dimensions"
        ],
        "summary": "Add a value",
        "description": "Add a value to a dimension (a cost centre, a profit centre, a project), for every company\nor one (`entity`), and from and until when lines may name it. Refused with 409\n`dimension_value_exists` for a code that is taken. Audited as `dimension_value.create`.",
        "operationId": "add_value_v1_dimensions__code__values_post",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dimension's code, e.g. `cost_centre`.",
              "examples": [
                "cost_centre"
              ],
              "title": "Code"
            },
            "description": "The dimension's code, e.g. `cost_centre`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValueInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/dimensions/{code}/values/{value}": {
      "patch": {
        "tags": [
          "dimensions"
        ],
        "summary": "Change a value",
        "description": "Rename a value, change the days lines may name it, or deactivate it. Lines posted with it\nkeep it; its code, dimension and company never change, and it is never deleted. Refused with\n422 `end_before_start`. Audited as `dimension_value.update` with the previous values.",
        "operationId": "update_value_v1_dimensions__code__values__value__patch",
        "parameters": [
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dimension's code, e.g. `cost_centre`.",
              "examples": [
                "cost_centre"
              ],
              "title": "Code"
            },
            "description": "The dimension's code, e.g. `cost_centre`."
          },
          {
            "name": "value",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The value's code, e.g. `CC-100`.",
              "examples": [
                "CC-100"
              ],
              "title": "Value"
            },
            "description": "The value's code, e.g. `CC-100`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ValueUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/direct-debit-exports": {
      "post": {
        "tags": [
          "direct debits"
        ],
        "summary": "Release direct debits as a pain.008 file",
        "description": "Release posted direct debit collections as a SEPA pain.008.001.08 file.\n\nThe rules of a pain.001 file apply: agents cannot release (403), nor the person who created\na collection; each is sent once (409 when already sent); a test copy makes no file (409).\nThe collection date is the receipt's date, at the earliest the TARGET2 business day after the\nnext one (D-1), rolled forward onto a TARGET2 business day. 422 when a collection cannot be\nreleased (see `problems` in `GET /v1/entities/{entity}/direct-debits`) or is no direct debit.\nDownload the file with `GET /v1/payment-exports/{id}/file`.",
        "operationId": "export_direct_debits_v1_direct_debit_exports_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DirectDebitExportInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentExportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/documents": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "List documents",
        "description": "Sales invoices, bills and credit notes of an entity, newest first (by document date,\nthen creation). Each row is a full document with its lines, party code and name, stored\noriginal and, once posted, its open amount. All filters combine with AND.",
        "operationId": "list_documents_v1_documents_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "enum": [
                      "purchase_bill",
                      "purchase_credit_note",
                      "sales_credit_note",
                      "sales_invoice"
                    ],
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Repeat the parameter to select several kinds: `sales_invoice`, `sales_credit_note`, `purchase_bill`, `purchase_credit_note`. Default: all.",
              "title": "Kind"
            },
            "description": "Repeat the parameter to select several kinds: `sales_invoice`, `sales_credit_note`, `purchase_bill`, `purchase_credit_note`. Default: all."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "enum": [
                      "draft",
                      "open",
                      "paid",
                      "pending_approval",
                      "posted",
                      "rejected",
                      "void"
                    ],
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "Repeat the parameter to select several statuses: `draft`, `pending_approval`, `posted`, `rejected`, `void`, `open` (posted with an open amount) and `paid` (posted, nothing open). Default: all.",
              "title": "Status"
            },
            "description": "Repeat the parameter to select several statuses: `draft`, `pending_approval`, `posted`, `rejected`, `void`, `open` (posted with an open amount) and `paid` (posted, nothing open). Default: all."
          },
          {
            "name": "party",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Customer or vendor code (e.g. `C-DE`) or id.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer or vendor code (e.g. `C-DE`) or id."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "ISO 4217 code of the document currency, e.g. `EUR`.",
              "examples": [
                "EUR"
              ],
              "title": "Currency"
            },
            "description": "ISO 4217 code of the document currency, e.g. `EUR`."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Document date from, inclusive (ISO 8601, `2026-09-01`).",
              "title": "Start"
            },
            "description": "Document date from, inclusive (ISO 8601, `2026-09-01`)."
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Document date to, inclusive (ISO 8601, `2026-09-30`).",
              "title": "End"
            },
            "description": "Document date to, inclusive (ISO 8601, `2026-09-30`)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the number, vendor invoice number, order or buyer reference, notes, or the party's name or code (case-insensitive, any part).",
              "title": "Q"
            },
            "description": "Text in the number, vendor invoice number, order or buyer reference, notes, or the party's name or code (case-insensitive, any part)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "Most documents returned, 1 to 1000.",
              "default": 100,
              "title": "Limit"
            },
            "description": "Most documents returned, 1 to 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DocumentOut"
                  },
                  "title": "Response List Documents V1 Documents Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Create an invoice, bill or credit note",
        "description": "Create a sales invoice, purchase bill or credit note for a customer or vendor.\n\nTax is determined per line by data-vNext (place of supply, liable party, rate); the\ndecision and its legal reference are stored on each line. The response holds the\ndocument and, with `submit=true`, the submit result: its `policy` is `allow` (posted,\nnumbered) or `require_approval` (status `pending_approval`, `approval_id` set); a\n`deny` answers 403. Refuses with 404 for an unknown entity, party or account, 422 for\ninvalid lines or a credit note above the open amount of the document it credits, and 409\nwhen submitting for a draft customer or vendor (create with `submit=false` instead) or\nwhen crediting a document that is not posted. A credit note line with `credits_line` and a\n`unit_price` crediting a line that had a discount must state its discount (`0` for none):\n422 `credit_discount_required` otherwise. A credit note of a bill blocked for payment posts\nwithout settling the bill; the credit stays open until the variance is approved.",
        "operationId": "create_document_v1_documents_post",
        "parameters": [
          {
            "name": "submit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` (default): also submit the document through the approval policy (it is posted, or waits for approval). `false`: keep it as a draft.",
              "default": true,
              "title": "Submit"
            },
            "description": "`true` (default): also submit the document through the approval policy (it is posted, or waits for approval). `false`: keep it as a draft."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/einvoice": {
      "post": {
        "tags": [
          "e-invoicing"
        ],
        "summary": "Receive an e-invoice as a draft bill",
        "description": "Turn a structured e-invoice into a draft bill (no model involved).\n\nSend `multipart/form-data`: the invoice in the form field `file`, plus the form fields\n`entity` (required), `vendor`, `create_vendor` and `submit`. The file is stored as the\nbill's source document. An invoice that breaks a fatal EN 16931 or XRechnung rule is\nstored but not booked (`status: invalid`) and the violations are listed by rule id.\nThe result's `status` is `draft`, `pending_approval` or `posted` (with `submit=true`, as\nthe approval policy decides; the bill of a draft vendor stays a draft with a warning),\n`invalid`, or `needs_review` (unknown vendor with `create_vendor=false`, or a negative\ntotal). The same file or vendor invoice number is refused with 409. With `submit=true`, an\ninvoice dated in a closed period is refused with 409 (`period_closed`, nothing is kept): its\n`hint` says to import it with `submit=false` and give the draft bill a date in an open period\n(`PATCH /v1/documents/{document_id}`), then submit it. A foreign vendor's VAT that cannot be\nreclaimed is booked as part of the cost, so the bill's total is the invoice total; a bill\nquoting a purchase order none of the vendor's waits for a second person.",
        "operationId": "import_einvoice_v1_documents_einvoice_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_import_einvoice_v1_documents_einvoice_post"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EInvoiceResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/preview": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Preview a document and its VAT",
        "description": "The document the body would create, with the tax of every line determined and its\ntotals, without storing anything (entry forms show live VAT with it). The body is the\nsame as for creating a document and is validated the same way (404, 409, 422); the\nreturned `id` is a placeholder, `status` is `draft` and `number` is null. For a sales\ninvoice or credit note `missing_content` warns of what the entity's or the customer's record\nlacks to be a lawful invoice; it does not refuse (printing and sending do).",
        "operationId": "preview_document_v1_documents_preview_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/documents/{document_id}": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Get a document",
        "description": "One document with its lines, tax decisions and, once posted, its open amount, by id\nor by number (e.g. INV-2026-000001; a number used in several entities answers 409, use\nthe id). The `ETag` response header names the version; send it back as `If-Match` when\nyou change, submit or void the document. 404 when it does not exist.",
        "operationId": "get_document_v1_documents__document_id__get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "documents"
        ],
        "summary": "Change a draft document",
        "description": "Change a draft: header fields, party and lines (which replace all lines).\n\nOmitted fields keep their value, `null` clears an optional one. The tax of every line\nis determined again. Only drafts change (409 otherwise); a rejected document must be\nreopened first (`POST .../reopen`). Repeating the same change gives the same draft; send\n`If-Match` so a change made in the meantime is not overwritten (412 when the document\nis at another version). 422 when the result is invalid, e.g. a negative total.",
        "operationId": "update_document_v1_documents__document_id__patch",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed document answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed document answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/documents/{document_id}/allocations": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "List what settled a document",
        "description": "The payments and credit notes that settled the document (or, for a credit note,\nwhat it settled), oldest first. Allocations still waiting for approval are listed with\ntheir `status`; rejected ones too.",
        "operationId": "document_allocations_v1_documents__document_id__allocations_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AllocationOut"
                  },
                  "title": "Response Document Allocations V1 Documents  Document Id  Allocations Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/documents/{document_id}/dispatches": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "List what was sent of an invoice and how it can be sent",
        "description": "The sent log of an invoice or credit note (when, to whom, which attachments, the\n`Message-ID`), oldest first, with what a send would do: whether this server sends e-mail\nat all (`sending_configured`), the recipient used without `to`, `allowed_recipients` (the\ncustomer's own addresses a send may go to), the default format (`pdf`) and whether the\nXRechnung XML would be attached. 422 for a document that is not a sales\ninvoice or credit note. The sent log is evidence: it is readable whatever the state of the\ncustomer's or the entity's records, and for a draft it is empty (printing and sending, not\nreading, answer 409).",
        "operationId": "document_dispatches_v1_documents__document_id__dispatches_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Dispatches"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/documents/{document_id}/doubtful": {
      "put": {
        "tags": [
          "close"
        ],
        "summary": "Mark an invoice doubtful",
        "description": "Mark a posted customer invoice doubtful, or change its percent: the allowance run covers\nthat share of what is open on it (a specific allowance) instead of its aging bucket's\npercent. Posts nothing by itself. Refused: 404 for an unknown invoice, 422 when it is not a\nposted customer invoice (`doubtful_not_invoice`).",
        "operationId": "mark_doubtful_v1_documents__document_id__doubtful_put",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DoubtfulInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DoubtfulOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "close"
        ],
        "summary": "Unmark a doubtful invoice",
        "description": "The invoice is no longer doubtful: the general allowance covers it again. 404 when it is\nnot marked.",
        "operationId": "unmark_doubtful_v1_documents__document_id__doubtful_delete",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/documents/{document_id}/dunning-block": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "Get whether the reminders of an invoice are stopped",
        "description": "The stop on the invoice's reminders, with who set it, when and why; `block` is null when\nreminders go out as usual.",
        "operationId": "get_dunning_block_v1_documents__document_id__dunning_block_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DunningBlockState"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "dunning"
        ],
        "summary": "Stop the reminders of an invoice",
        "description": "Stop the reminders of a posted sales invoice, with why (a dispute, for instance): the\nreminder proposal leaves it out and lists it apart with the reason, so no letter names it\nand it is charged no fee and no interest while the stop holds. It stays open and payable.\nA person does it (the policy action `release_dunning`; an agent key answers 403). 409\n`dunning_block_exists` when its reminders are stopped already, 409\n`dunning_block_not_invoice` for another document. Needs an `Idempotency-Key`.",
        "operationId": "block_reminders_v1_documents__document_id__dunning_block_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DunningBlockInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DunningBlockState"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      },
      "delete": {
        "tags": [
          "dunning"
        ],
        "summary": "Resume the reminders of an invoice",
        "description": "Lift the stop: the invoice is due its next reminder again as if it had not been stopped\n(interest runs from its due date or the last day a letter charged, as before). The stop and\nwho lifted it stay on record. A person does it; 409 `dunning_block_missing` when its\nreminders are not stopped.",
        "operationId": "resume_reminders_v1_documents__document_id__dunning_block_delete",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DunningBlockState"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/documents/{document_id}/file": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Download the original file of a document",
        "description": "The original a document was entered from: the e-invoice XML or PDF, or the PDF or\nimage read by bill capture. 404 when the document has none.\n\nShown inline only when its bytes are of an allowed type (PDF, PNG, JPEG, WebP, XML\nwithout HTML or SVG markup); anything else is an `application/octet-stream`\nattachment. Never cached, never embeddable by another site.",
        "operationId": "document_file_v1_documents__document_id__file_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true`: send as an attachment (download); `false` (default): inline when the type is safe to show.",
              "default": false,
              "title": "Download"
            },
            "description": "`true`: send as an attachment (download); `false` (default): inline when the type is safe to show."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The stored original, byte for byte (SHA-256 in X-Content-SHA256).",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "text/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/webp": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/documents/{document_id}/files": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "List the files of a document",
        "description": "Every file stored for an invoice, bill or credit note, oldest first: the original it\nwas entered from (`received` or `captured`), its archived outputs (`archived_output`: the\nPDF, ZUGFeRD hybrid or XRechnung exactly as they were first output, see `GET\n/v1/documents/{id}/pdf`) and the originals attached afterwards (`attached`). Each file has its\nSHA-256, who stored it and when. The list is empty for a document without a file; 404 for an\nunknown document.",
        "operationId": "list_files_v1_documents__document_id__files_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FileOut"
                  },
                  "title": "Response List Files V1 Documents  Document Id  Files Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Attach a scanned or received original to a document",
        "description": "Add a scanned or received original to a document of any kind and status: a bill that was\nentered by hand, an open receivable or payable the opening import brought in, a credit note.\nSend `multipart/form-data` with the file in the form field `file`.\n\nAttaching is append-only: nothing is ever replaced or removed, a second file is another\nattachment, and each one has its own audit event (`document.attach`, in the document's\nhistory) with the file's SHA-256. The file is stored under its content, so the same bytes are\nstored once. Refused with 422 for an empty file, one over 20 MB or one that is not a PDF or\nan image by its bytes, 409 when the document already has this file (as its original or an\nattachment), 404 for an unknown document. A retry with the same `Idempotency-Key` returns the\nfirst answer and attaches nothing more.",
        "operationId": "attach_file_v1_documents__document_id__files_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_attach_file_v1_documents__document_id__files_post"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FileOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/{document_id}/files/{file_id}": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Download a file of a document",
        "description": "One file of the document: its original, an archived output or an attachment, byte for byte.\nShown inline only when its bytes are of an allowed type (as for `GET\n/v1/documents/{id}/file`); never cached, never embeddable by another site. 404 when the\ndocument has no such file, 409 when the stored bytes no longer match their SHA-256. An\narchived output is served whatever the state of the customer's records now.",
        "operationId": "download_file_v1_documents__document_id__files__file_id__get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "file_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of a stored file (`GET /v1/documents/{document_id}/files`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "File Id"
            },
            "description": "Id of a stored file (`GET /v1/documents/{document_id}/files`)."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true`: send as an attachment (download); `false` (default): inline when the type is safe to show.",
              "default": false,
              "title": "Download"
            },
            "description": "`true`: send as an attachment (download); `false` (default): inline when the type is safe to show."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The stored file, byte for byte (SHA-256 in X-Content-SHA256).",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "text/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/webp": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/documents/{document_id}/history": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Get the history of a document",
        "description": "Audit events of the document, its journal entries (submissions, approvals,\nrejections, also of earlier attempts) and its stored files (original, archived outputs,\nattachments), oldest first.",
        "operationId": "document_history_v1_documents__document_id__history_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AuditEventOut"
                  },
                  "title": "Response Document History V1 Documents  Document Id  History Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/documents/{document_id}/mark-sent": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Record that an invoice or credit note was handed over",
        "description": "Record that a person handed the invoice or credit note to the customer outside this\nsystem: they e-mailed the downloaded PDF from their own mailbox, posted it, or put it on the\ncustomer's portal. Nothing is sent. The sent log (`GET .../dispatches`) and the document's\nhistory get a row with the `channel`, the `recipient`, the day it was handed over and the\nSHA-256 of the archived file that was handed over: `file_id` names it (an archived output of\n`GET .../files`); omitted, it is the invoice PDF, which is archived now if it was never output\n(then the content gate applies as for the PDF). Marking is repeatable: each call is another\nhand-over.\n\nOnly a person records: the approval policy action `send_document` is denied to agents by\ndefault (403 `policy_denied`), and an agent key answers 403 whatever the policy says. 404 for\nan unknown document or `file_id`, 409 when the document is not posted (or, without `file_id`,\nthe content gate refuses the PDF), 422 for a document that is not a sales invoice or credit\nnote, a day before the document's date or in the future. A retry with the same\n`Idempotency-Key` returns the first answer and records nothing more.",
        "operationId": "mark_sent_v1_documents__document_id__mark_sent_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarkSentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DispatchOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/{document_id}/match": {
      "get": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Get Document Match",
        "description": "How a bill matches the purchase order its order reference names: per line, the\norder line, price and quantity variances (2-way or 3-way), the tolerance and whether\nthe bill is blocked for payment. 404 when the bill was never matched.",
        "operationId": "get_document_match_v1_documents__document_id__match_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Match Document",
        "description": "Match a bill to its purchase order again (bills are matched when submitted). An\napproved variance stays approved. Safe to repeat.",
        "operationId": "match_document_v1_documents__document_id__match_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/documents/{document_id}/match/approve": {
      "post": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Approve Document Variance",
        "description": "Approve a bill's purchase order variance with a reason, which releases its payment\nblock (four eyes: not the person who entered or submitted the bill; agents never).\nThe same as approving its request with `POST /v1/approvals/{id}/approve`.",
        "operationId": "approve_document_variance_v1_documents__document_id__match_approve_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VarianceApproval"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/documents/{document_id}/pdf": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "Download an invoice or credit note as PDF",
        "description": "The invoice or credit note as an A4 PDF: the entity's name, address, VAT number and\nbank account, the customer's address and references (customer number, buyer reference,\npurchase order), the lines with VAT, the VAT per rate, the totals, payment terms with a\ncash discount, and the notes. The labels and the way numbers and dates are written follow\nthe customer's language. A Swiss entity's invoice that is not settled gets the Swiss\nQR-bill payment part (on the last page, or on a page of its own when it does not fit). In a\ntest copy every page says it is a test copy and not valid, there is no QR-bill, and\n`format=zugferd` is refused (409, ADR-0039).\n\n**Archived as issued.** The first time an output is asked for, its exact bytes are stored\nwith their SHA-256 and linked to the document (`GET /v1/documents/{id}/files`, source\n`archived_output`). Every later request for the same output (the same `format` and the\nsame `language`, `qr_bill` and `profile`, an omitted `language` being the customer's\nlanguage) returns those bytes and renders nothing, so an auditor gets what the customer\ngot, also after the customer's address was corrected or the invoice was paid. Another\n`language`, `qr_bill` or `profile` is another output, archived the same way. A stored\noutput is returned even when the records lack content the law requires now (the gate\ndecides the first output only). **The first output needs the `post` scope** and an organization\nthat is not suspended: anyone else (a viewer, an auditor) gets `409` `not_issued` until a\nperson who may post has downloaded it; what is archived is read with `read`. 422 for a\ndocument that is not a sales invoice or credit note (and for `format=zugferd` of a non-German\nentity or an invoice that breaks an EN 16931 rule); 409 when the document is not posted, and\n409 `invoice_content_incomplete` when the entity's or the customer's record lacks content the\nlaw requires on an invoice (name, place or address, VAT number: Art. 26 MWSTG, § 14 UStG):\n`missing` lists each field with its legal basis and the record to complete, and\n`missing_content` on the document says it beforehand.",
        "operationId": "document_pdf_v1_documents__document_id__pdf_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "pdf",
                "zugferd"
              ],
              "type": "string",
              "description": "`pdf` (default): the invoice PDF; `zugferd`: the hybrid PDF with the EN 16931 invoice embedded as `factur-x.xml` (ZUGFeRD / Factur-X; German entities). **Not yet verified for PDF/A-3**: no PDF/A validator runs in CI (backlog B-55).",
              "default": "pdf",
              "title": "Format"
            },
            "description": "`pdf` (default): the invoice PDF; `zugferd`: the hybrid PDF with the EN 16931 invoice embedded as `factur-x.xml` (ZUGFeRD / Factur-X; German entities). **Not yet verified for PDF/A-3**: no PDF/A validator runs in CI (backlog B-55)."
          },
          {
            "name": "profile",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "en16931",
                "xrechnung"
              ],
              "type": "string",
              "description": "With `format=zugferd`: the profile of the embedded XML, `en16931` (EN 16931, default) or `xrechnung` (XRechnung 3.0; refused when it breaks an XRechnung rule, e.g. a missing buyer reference).",
              "default": "en16931",
              "title": "Profile"
            },
            "description": "With `format=zugferd`: the profile of the embedded XML, `en16931` (EN 16931, default) or `xrechnung` (XRechnung 3.0; refused when it breaks an XRechnung rule, e.g. a missing buyer reference)."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "it",
                    "sv"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Language of the labels and dates: `de`, `fr`, `it`, `en` or `sv`. Omitted: the customer's language, else the language of its country.",
              "title": "Language"
            },
            "description": "Language of the labels and dates: `de`, `fr`, `it`, `en` or `sv`. Omitted: the customer's language, else the language of its country."
          },
          {
            "name": "qr_bill",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Swiss entities, `format=pdf`: add the QR-bill payment part to an invoice that still has an open amount (`false` leaves it out).",
              "default": true,
              "title": "Qr Bill"
            },
            "description": "Swiss entities, `format=pdf`: add the QR-bill payment part to an invoice that still has an open amount (`false` leaves it out)."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true`: send as an attachment (download); `false` (default): inline.",
              "default": false,
              "title": "Download"
            },
            "description": "`true`: send as an attachment (download); `false` (default): inline."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF, as archived at its first output (SHA-256 in X-Content-SHA256).",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/documents/{document_id}/reopen": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Reopen a rejected document",
        "description": "Return a rejected document to draft, to correct it and submit it again (audited\nwith the `reason`). The rejected journal entry stays in the document's history. Only a\nrejected document reopens (409 otherwise, also when its vendor invoice number was\nrecorded again on another bill).",
        "operationId": "reopen_document_v1_documents__document_id__reopen_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentAction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/{document_id}/send": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Send an invoice or credit note by e-mail",
        "description": "E-mail the invoice or credit note to the customer, with the PDF attached, as archived (see\n`GET /v1/documents/{id}/pdf`; `format` is `pdf` by default; `zugferd` is the hybrid, not yet\nverified for PDF/A-3) and, for a German public-sector customer with a Leitweg-ID, the\nXRechnung XML next to it. The mail goes to `to`, which may only name the customer's own\naddresses (its e-invoice address, e-mail address and contacts' e-mail addresses), or without\n`to` to the customer's e-invoice or billing address. The answer records what was sent: time,\nrecipients, subject, `Message-ID` and the attachments with their SHA-256; the same is in the\ndocument's sent log and in its history.\n\nOnly a person sends: the approval policy action `send_document` is denied to agents by\ndefault (403 `policy_denied`), and an agent key answers 403 whatever the policy says. 409\nwhen this server has no mail server configured (`sending is not configured`: download the PDF\ninstead; `sending_configured` in `GET .../dispatches` says so beforehand), in a test\ncopy (it never e-mails customers, who may be real ones), or when the document is not\nposted; 422 when there is no recipient, an address is invalid or is not one of the\ncustomer's (add it to the customer first), or the XML breaks a rule; 409\n`invoice_content_incomplete` when the entity's or the customer's record lacks content the law\nrequires (as for the PDF); 429 (`rate_limited`)\nbeyond the organization's hourly limit of messages (default 60); 502 (`mail_failed`) when the\nmail server does not accept the message, in which case nothing is recorded and the request\ncan be repeated. A retry with the same `Idempotency-Key` returns the first answer and sends\nnothing.",
        "operationId": "send_document_v1_documents__document_id__send_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DispatchOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "A per-organization limit was reached, e.g. messages sent per hour (`rate_limited`, with `retry_after_seconds`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/{document_id}/submit": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Submit a draft document",
        "description": "Post a draft through the approval policy, or queue it for approval. Only drafts\nsubmit (409 otherwise, also when the customer or vendor is still a draft). The submit\nresult's `policy` is `allow` (document posted and numbered) or `require_approval`\n(status `pending_approval`, a second person decides); `deny` answers 403. A bill that quotes\na purchase order none of its vendor's in its company waits for a second person whatever the\npolicy allows; the result's `reason` says why. A credit note is\nchecked again against the document it credits: 409 when it now exceeds that document's open\namount, 422 when its lines without an obligation would credit more than the invoice's other\nlines left (another credit note took it since the draft). With `If-Match`, only the version\nyou read is submitted (412 if it changed since).",
        "operationId": "submit_document_v1_documents__document_id__submit_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed document answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed document answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentResult"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/documents/{document_id}/void": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Void a draft document",
        "description": "Void a draft: it keeps no number, posts nothing and can no longer change (409 for\nany other status; 412 when `If-Match` names a version that is no longer current). A\nvendor invoice number or file of a void bill can be entered again.",
        "operationId": "void_document_v1_documents__document_id__void_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed document answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed document answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DocumentAction"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required",
        "x-if-match": "optional"
      }
    },
    "/v1/documents/{document_id}/write-off": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Write off what is open on a customer invoice",
        "description": "Write off all or part of what is open on a posted sales invoice the customer will not pay.\n\nAn internal entry, not a credit note: nothing goes to the customer. It credits the\nreceivable and debits the bad-debt account (role `bad_debt_expense`): with\n`vat_treatment=correct` the output VAT on the amount is corrected too (the loss is final) and\nthe VAT return shows the reduction like a credit note's; with `keep` the whole amount goes to\nthe bad-debt account. A foreign-currency invoice is written off at the rate it is carried at.\nIt always waits for a second person (`submit.status` `pending_approval`, decided on\nApprovals); meanwhile it reserves its amount on the invoice. Refused: 404 for an unknown\ninvoice; 422 when it is not a posted customer invoice (`write_off_not_invoice`), nothing is\nopen (`write_off_nothing_open`), the amount exceeds what is open (`more_than_open`), the date\nis after today (`write_off_in_future`) or before the invoice or its latest settlement\n(`write_off_before_settlement`), the VAT is to be kept on the cash basis\n(`write_off_keep_cash_basis`: no VAT is owed on money never received), or the chart has no\nbad-debt account (`role_missing`); 409\nwhen the period is closed or the customer is blocked.",
        "operationId": "write_off_v1_documents__document_id__write_off_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WriteOffInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WriteOffResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/{document_id}/write-off/recovery": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Book money received after a write-off",
        "description": "The customer paid all or part of a written-off invoice after all. The invoice stays\nwritten off; the entry debits the bank account and credits the bad-debt account (a recovery).\nWhere the write-off corrected the output VAT (now or later), the VAT is owed again in\nproportion to what was received (CH MWSTG Art. 41, DE UStG § 17 Abs. 2): the VAT return of\nthe period shows it like a sale. Submitted under the approval policy (`submit.status`\n`posted` or `pending_approval`). Refused: 404 for an unknown invoice or write-off of it; 422\nwhen the write-off is not posted (`write_off_not_posted`), the amount is more than what is\nwritten off and not received yet (`recovery_more_than_written_off`), the date is after today\n(`follow_up_in_future`) or before the write-off (`follow_up_before_write_off`), or the account\nis no bank account (`not_a_bank_account`); 409 while something else booked on the write-off\nwaits for approval (`write_off_follow_up_waiting`) or when the period is closed.",
        "operationId": "write_off_recovery_v1_documents__document_id__write_off_recovery_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecoveryInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FollowUpResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/{document_id}/write-off/vat-correction": {
      "post": {
        "tags": [
          "documents"
        ],
        "summary": "Correct the VAT a write-off kept",
        "description": "The loss of a write-off that kept the VAT (`vat_treatment=keep`) is final now: the output\nVAT on what is written off and was not received after all is corrected, dated the day the\nloss became final, as a write-off that corrects it at once would have (CH MWSTG Art. 41, DE\nUStG § 17 Abs. 2). Its VAT lines go back to the VAT accounts with their tax tags; the\nbad-debt account is relieved by as much. Submitted under the approval policy. Refused: 404\nfor an unknown invoice or write-off of it; 422 when the write-off is not posted\n(`write_off_not_posted`), its VAT is corrected already (`write_off_vat_corrected`),\neverything was received after all (`write_off_all_recovered`) or the date is after today or\nbefore the write-off (`follow_up_in_future`, `follow_up_before_write_off`); 409 while\nsomething else booked on the write-off waits for approval (`write_off_follow_up_waiting`).",
        "operationId": "write_off_vat_correction_v1_documents__document_id__write_off_vat_correction_post",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatCorrectionInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FollowUpResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/documents/{document_id}/write-offs": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "List the write-offs of an invoice",
        "description": "The write-offs of the invoice, oldest first, with their reason, VAT treatment and status\n(waiting ones and rejected ones too).",
        "operationId": "document_write_offs_v1_documents__document_id__write_offs_get",
        "parameters": [
          {
            "name": "document_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Document Id"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WriteOffOut"
                  },
                  "title": "Response Document Write Offs V1 Documents  Document Id  Write Offs Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/einvoices/check": {
      "post": {
        "tags": [
          "e-invoicing"
        ],
        "summary": "Check an e-invoice",
        "description": "Parse an e-invoice and check the EN 16931 and XRechnung rules; nothing is stored.\n\nSend `multipart/form-data` with the invoice in the form field `file`. The response says\nwhether the invoice is `valid` (no fatal violation), which profile and syntax it is, the\nviolations by rule id and the parsed invoice. A file that cannot be read as an e-invoice\nor is larger than 20 MB answers 422.",
        "operationId": "check_einvoice_v1_einvoices_check_post",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_check_einvoice_v1_einvoices_check_post"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/entities": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "List Entities",
        "description": "All legal entities of the organization, ordered by code. The `code` is what the other\nendpoints take as `{entity}`.",
        "operationId": "list_entities_v1_entities_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EntityOut"
                  },
                  "title": "Response List Entities V1 Entities Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "setup"
        ],
        "summary": "Create an entity",
        "description": "Create a legal entity with its chart of accounts, and optionally its fiscal years.\n\nThe accounts are copied from the chart template `chart` (see `GET /v1/charts`, which marks\nthe country's standard chart); the template must carry every role the services need.\n`fiscal_years` lists the years whose periods are opened at once, on `fiscal_calendar`.\nRefused with 409 when the entity code is taken, in a test copy (`company_in_test_copy`: it\ntakes its companies from Production; add the company there and make a new copy), and in an\norganization provisioned without a company, which waits for its administrator's setup\n(`setup_not_done`: `POST /v1/setup` makes the first company, then Test); 422 for an unknown\nchart or an invalid calendar, and 403 when the approval policy denies `manage_accounts`\n(always for agents).",
        "operationId": "create_entity_v1_entities_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntityInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "Get Entity",
        "description": "One entity with its legal data, address, contact and e-invoicing address, its posting\napproval limit and a request to raise or remove it that waits (`posting_limit_request`). The\npath takes the entity code or its id.",
        "operationId": "get_entity_v1_entities__entity__get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityDetailOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "setup"
        ],
        "summary": "Update Entity",
        "description": "Change an entity's name, VAT number, address, contact or e-invoicing address (the\nseller on XRechnung). Only the fields sent with a value change; null or omitted leaves a\nfield as it is. Code, country, currency and framework cannot be changed. A Swiss or German\nVAT number must have the format of a UID or USt-IdNr (422). Refused with 403\nwhen the approval policy denies the action `manage_accounts`. Audited as `entity.update`.\n\n`posting_approval_limit` is the exception: null removes it. Only a person with the admin\nscope changes it; a lower limit applies at once, while raising or removing it waits for a\nsecond person (policy action `change_posting_limit`): the answer then keeps the old limit and\nnames the request in `posting_limit_request`, approved under Approvals.",
        "operationId": "update_entity_v1_entities__entity__patch",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntityUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EntityDetailOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/accounts": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "List Accounts",
        "description": "The entity's chart of accounts ordered by code, inactive accounts included\n(`active`). Control accounts (`is_control`) take postings only from their subledger.",
        "operationId": "list_accounts_v1_entities__entity__accounts_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Keep accounts whose code starts with this text or whose name, or a translation of it, contains it (case-insensitive); omit for the whole chart.",
              "examples": [
                "65"
              ],
              "title": "Q"
            },
            "description": "Keep accounts whose code starts with this text or whose name, or a translation of it, contains it (case-insensitive); omit for the whole chart."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AccountOut"
                  },
                  "title": "Response List Accounts V1 Entities  Entity  Accounts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "setup"
        ],
        "summary": "Add an account",
        "description": "Add an account to the entity's chart. Refused with 409 when the code is taken, with 422\nwhen the number is not one word, the name is empty or more than one line, or the report line\nis unknown or holds another type of account (`pl.opex.other` holds expense accounts, never\nrevenue), and with 403 when the approval policy denies the action `manage_accounts` (always\nfor agents). An\naccount with a `role` is the account the services use for that purpose, e.g. `bank`.\nAudited as `account.create`.",
        "operationId": "add_account_v1_entities__entity__accounts_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/accounts/{code}": {
      "patch": {
        "tags": [
          "setup"
        ],
        "summary": "Change an account",
        "description": "Rename an account, give it a role, take it away, change its statement line or deactivate\nit. Only the fields sent change; `role: null` takes the role away. A chart is the customer's\nown (imported), so an existing account must be able to take the role a service looks for.\n\nA role says which account a service posts to, so who holds it is controlled. The role must\nbe one the services know and fit the account's type (422); only one account of the entity\nholds it (409); a control role (`bank`, `ar_control`, `ap_control`, `fixed_asset_cost`,\n`accumulated_depreciation`, `annual_result`, ...) is refused (409) on an account that already\nhas postings from outside its subledger. A change to or from a control or required role is a\nrequest for a second person (the approval policy's `change_required_account_role`, default\n`require_approval`): the answer is `202` with `status` `pending_approval` and the\n`approval_id`, and the account changes when another person approves it\n(`POST /v1/approvals/{approval_id}/approve`). The role of an ordinary account changes at\nonce; a rename alone always does. An account cannot be deactivated (409, naming why) while it\nholds a role, is a control account, carries a balance (a P&L account: a result in a fiscal year\nnot closed to zero), is named by unfinished work (an entry, invoice, bill, purchase order,\npayment or recurring invoice), or while a fixed asset, product, subscription, contract, party,\nbank account or setting posts to it. The report\nline must be one that holds the account's type (422).\nThe number, type and currency are fixed. Every change is audited with the previous value\n(`account.role.change`, `account.update`); a request, a rejection and an approval are audited\ntoo. Repeating a change that has been applied changes nothing. Refused with 403 when the\npolicy denies `manage_accounts` (always for agents), 404 for an unknown account, 409 for the\nrefusals above and for a second pending request on the account.",
        "operationId": "update_account_v1_entities__entity__accounts__code__patch",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Account code in the entity's chart, e.g. `6510`.",
              "examples": [
                "6510"
              ],
              "title": "Code"
            },
            "description": "Account code in the entity's chart, e.g. `6510`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountChange"
                }
              }
            }
          },
          "202": {
            "description": "Waits for a second person.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountChange"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/analytics/breakdowns": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Top customers, vendors, currencies and expenses",
        "description": "What a range is made of. `customers`: invoiced revenue per customer; `vendors`: billed spend per vendor; `currency`: invoiced revenue per document currency. All three are posted documents by document date, invoices less credit notes, at their net total in the functional currency (the document list filtered by the same party or currency, dates and `posted` status has the same documents). `expense_mix`: the expense accounts of the ledger by report line. The largest `limit` rows, the rest as one row `other`.",
        "operationId": "breakdowns_v1_entities__entity__analytics_breakdowns_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "currency",
                "customers",
                "expense_mix",
                "vendors"
              ],
              "type": "string",
              "description": "What to break down.",
              "title": "Kind"
            },
            "description": "What to break down."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-01-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 50,
              "minimum": 1,
              "description": "Most rows before the rest is grouped.",
              "default": 10,
              "title": "Limit"
            },
            "description": "Most rows before the rest is grouped."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Breakdown"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/analytics/flux": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Flux analysis of a period",
        "description": "Flux analysis: each account's P&L movement or balance-sheet balance against the\nprevious regular period. A row is flagged when the variance reaches the materiality\nand 10% of the comparison; flagged rows come first. Amounts are in the entity's\nfunctional currency. Profit-and-loss accounts compare the period's movement, balance-sheet\naccounts the balance at the period's end. Without an earlier period the comparison is\nempty. An unknown year or period answers 404.",
        "operationId": "flux_v1_entities__entity__analytics_flux_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "maximum": 2100,
              "minimum": 2000,
              "description": "The fiscal year, e.g. 2026.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. 2026."
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "description": "Period number within the year, from 1; adjustment periods follow the regular ones.",
              "examples": [
                9
              ],
              "title": "Period"
            },
            "description": "Period number within the year, from 1; adjustment periods follow the regular ones."
          },
          {
            "name": "materiality",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number",
                  "minimum": 0.0
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                }
              ],
              "description": "Threshold in the entity's functional currency (decimal, e.g. 1000.00) above which a difference or amount is flagged; default 1000.",
              "examples": [
                "1000.00"
              ],
              "default": "1000",
              "title": "Materiality"
            },
            "description": "Threshold in the entity's functional currency (decimal, e.g. 1000.00) above which a difference or amount is flagged; default 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Flux"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/analytics/insights": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "What moved, in words",
        "description": "The accounts whose movement (profit and loss) or balance (balance sheet) differs from the comparison range by at least the materiality and 10%, largest first, each with one sentence made from its numbers by a fixed template; and the entries of the range that carry a risk flag. The same rules as `/flux` and `/unusual-entries`, for any range.",
        "operationId": "insights_v1_entities__entity__analytics_insights_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-01-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "compare",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "previous",
                "year_ago"
              ],
              "type": "string",
              "description": "The range figures are compared with: `previous` is the same number of whole months (or days, if the range is not whole months) right before the range, `year_ago` the same dates a year earlier.",
              "default": "previous",
              "title": "Compare"
            },
            "description": "The range figures are compared with: `previous` is the same number of whole months (or days, if the range is not whole months) right before the range, `year_ago` the same dates a year earlier."
          },
          {
            "name": "materiality",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number",
                  "minimum": 0.0
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                }
              ],
              "description": "Threshold in the entity's functional currency (decimal, e.g. 1000.00) above which a difference or amount is flagged; default 1000.",
              "examples": [
                "1000.00"
              ],
              "default": "1000",
              "title": "Materiality"
            },
            "description": "Threshold in the entity's functional currency (decimal, e.g. 1000.00) above which a difference or amount is flagged; default 1000."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Most flagged accounts and entries listed.",
              "default": 10,
              "title": "Limit"
            },
            "description": "Most flagged accounts and entries listed."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Insights"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/analytics/kpis": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Key figures with comparison",
        "description": "Ten figures for a range, each against the same figure for a comparison range, each with a small trend: revenue, gross margin %, operating expenses, net income, cash, receivables, payables, DSO, DPO and working capital. Computed on the server from the posted ledger by report line (the definitions are the `metric` list of `GET .../analytics/series`); a flow is the range's total, a stock the balance on its last day. `delta` is the difference, `favourable` says whether it is good news.",
        "operationId": "kpis_v1_entities__entity__analytics_kpis_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-01-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "compare",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "previous",
                "year_ago"
              ],
              "type": "string",
              "description": "The range figures are compared with: `previous` is the same number of whole months (or days, if the range is not whole months) right before the range, `year_ago` the same dates a year earlier.",
              "default": "previous",
              "title": "Compare"
            },
            "description": "The range figures are compared with: `previous` is the same number of whole months (or days, if the range is not whole months) right before the range, `year_ago` the same dates a year earlier."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Kpis"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/analytics/series": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "A metric over time",
        "description": "One metric per calendar month, quarter or year over a range, from the posted ledger in the entity's functional currency. A flow (revenue, expenses, ...) is what moved in the period; a stock (cash, receivables, ...) and an aging are as of the period's end; a ratio is computed from the period's own figures. The first and last period are clamped to the range, so the sum of a flow over the periods is the report total for the range (`revenue` over a range is `revenue` of the profit-and-loss report for it), and a stock at the last period is the trial balance as of `end`. `by` splits a flow or stock into one line per report line or account; its `totals` are the sums. One aggregate query reads the range (an aging reads the open documents once). More than 60 periods answers 422: ask for a coarser `granularity`.\n\nThe metrics (`metric`):\n\n- `revenue` (amount): Credit less debit of the accounts of type revenue: the P&L's total revenue.\n- `expenses` (amount): Debit less credit of the accounts of type expense: the P&L's total expenses.\n- `net_income` (amount): Revenue less expenses: the P&L's net income.\n- `cost_of_sales` (amount): Debit less credit of the report line `pl.cost_of_sales`.\n- `operating_expenses` (amount): Debit less credit of the report lines `pl.opex.*` and `pl.depreciation`.\n- `gross_margin_pct` (percent): (Revenue on `pl.revenue` less cost of sales) / revenue on `pl.revenue` x 100; empty when there is no such revenue.\n- `cash` (amount): Balance at the period's end of the report lines starting `bs.assets.current.cash` (the Cash figure of the Role Center).\n- `receivables` (amount): Balance at the period's end of the report line `bs.assets.current.receivables` (the receivables control account in the ledger).\n- `payables` (amount): Balance at the period's end of the report line `bs.liabilities.current.payables` (the payables control account in the ledger).\n- `unearned_revenue` (amount): Balance at the period's end of the report line `bs.liabilities.current.contract_liabilities`: what customers paid or were billed for goods and services not yet delivered (contract liabilities, deferred revenue).\n- `working_capital` (amount): Report lines `bs.assets.current.*` less `bs.liabilities.current.*` at the period's end.\n- `dso` (days): Open receivables without VAT at the period's end (from the documents: the carrying amount of each open customer invoice and credit note times its net total over its total) / revenue of the period x days in the period.\n- `dpo` (days): Open payables without VAT at the period's end (from the vendor bills, as the receivables for DSO) / purchases of the period x days in the period; purchases are cost of sales plus the operating expenses that are bought on account (`pl.opex.*` except `pl.opex.personnel`). Capital purchases on account are not in purchases.\n- `receivables_aging` (amount): Open customer invoices less credit notes as of the period's end, in the functional currency at the booking rate, in the buckets of the aging report (current, 1-30, 31-60, 61-90, 90+ days past due). Equals `totals_functional` of `GET /v1/entities/{entity}/reports/aging` as of that day.\n- `payables_aging` (amount): Open vendor bills less credit notes as of the period's end, as the receivables aging.",
        "operationId": "series_v1_entities__entity__analytics_series_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "metric",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "cash",
                "cost_of_sales",
                "dpo",
                "dso",
                "expenses",
                "gross_margin_pct",
                "net_income",
                "operating_expenses",
                "payables",
                "payables_aging",
                "receivables",
                "receivables_aging",
                "revenue",
                "unearned_revenue",
                "working_capital"
              ],
              "type": "string",
              "description": "Which metric; see the list in the description.",
              "title": "Metric"
            },
            "description": "Which metric; see the list in the description."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-01-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, inclusive (ISO 8601).",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, inclusive (ISO 8601)."
          },
          {
            "name": "granularity",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "month",
                "quarter",
                "year"
              ],
              "type": "string",
              "description": "The size of the periods: `month`, `quarter` or `year` (calendar).",
              "default": "month",
              "title": "Granularity"
            },
            "description": "The size of the periods: `month`, `quarter` or `year` (calendar)."
          },
          {
            "name": "by",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "account",
                "none",
                "report_line"
              ],
              "type": "string",
              "description": "`none`: one line; `report_line` or `account`: one line each, for the metrics that can be split (revenue, expenses, cost_of_sales, operating_expenses, cash, receivables, payables). Others answer 422.",
              "default": "none",
              "title": "By"
            },
            "description": "`none`: one line; `report_line` or `account`: one line each, for the metrics that can be split (revenue, expenses, cost_of_sales, operating_expenses, cash, receivables, payables). Others answer 422."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Series"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/analytics/unusual-entries": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Unusual entries of a period",
        "description": "Posted entries of the period with risk flags: manual, created by an agent, round or\nlarge amount (10x materiality), weekend date, reversal. Each entry lists its `flags`\nand its total debits in the entity's functional currency. An unknown year or period answers\n404.",
        "operationId": "unusual_entries_v1_entities__entity__analytics_unusual_entries_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "maximum": 2100,
              "minimum": 2000,
              "description": "The fiscal year, e.g. 2026.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. 2026."
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "description": "Period number within the year, from 1; adjustment periods follow the regular ones.",
              "examples": [
                9
              ],
              "title": "Period"
            },
            "description": "Period number within the year, from 1; adjustment periods follow the regular ones."
          },
          {
            "name": "materiality",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number",
                  "minimum": 0.0
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                }
              ],
              "description": "Threshold in the entity's functional currency (decimal, e.g. 1000.00) above which a difference or amount is flagged; default 1000.",
              "examples": [
                "1000.00"
              ],
              "default": "1000",
              "title": "Materiality"
            },
            "description": "Threshold in the entity's functional currency (decimal, e.g. 1000.00) above which a difference or amount is flagged; default 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UnusualEntry"
                  },
                  "title": "Response Unusual Entries V1 Entities  Entity  Analytics Unusual Entries Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/appropriations": {
      "get": {
        "tags": [
          "year-end close"
        ],
        "summary": "List the appropriations of an entity",
        "description": "The posted appropriations, oldest first, with their destinations and whether a later\nreversal cancels them. An appropriation that waits for approval is in the approval queue\n(`GET /v1/approvals`) until it posts.",
        "operationId": "list_appropriations_v1_entities__entity__appropriations_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the resolutions on the result of this fiscal year.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "Only the resolutions on the result of this fiscal year."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AppropriationOut"
                  },
                  "title": "Response List Appropriations V1 Entities  Entity  Appropriations Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "year-end close"
        ],
        "summary": "Appropriate the result of a closed year",
        "description": "Book the shareholders' resolution on the result of a closed year as one entry dated\n`resolution_date` (source `appropriation`): for a profit `Dr annual_result / Cr` the\ndestinations (retained earnings, legal profit reserve, voluntary reserve, dividend payable),\nfor a loss the mirror image into the loss carried forward. A human (`close_fiscal_year`); by\ndefault a second person approves the entry. The sum of the destinations may not exceed what\nis left of the result (409 `appropriation_exceeds_remainder`, also refused by a database\ntrigger); a partial appropriation leaves the rest visible in `remainder`. For a Swiss\nentity the answer carries `warnings` and `withholding_tax`: a dividend bears 35 % withholding\ntax, which the company must deduct, booked by hand for now. Needs an `Idempotency-Key`.",
        "operationId": "appropriate_v1_entities__entity__appropriations_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AppropriationInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppropriationResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/appropriations/{appropriation_id}/reverse": {
      "post": {
        "tags": [
          "year-end close"
        ],
        "summary": "Reverse an appropriation",
        "description": "Withdraw an appropriation with an entry of its own (the lines swapped, dated `on`), through\nthe same approval as the appropriation; once posted its amount is free again and the year can\nbe reopened. A human (`close_fiscal_year`). 404 for an unknown appropriation; 409 for a\nreversal, or an appropriation that is already reversed. Needs an `Idempotency-Key`.",
        "operationId": "reverse_appropriation_v1_entities__entity__appropriations__appropriation_id__reverse_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "appropriation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the appropriation (`GET /v1/entities/{entity}/appropriations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Appropriation Id"
            },
            "description": "Id of the appropriation (`GET /v1/entities/{entity}/appropriations`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AppropriationReverseInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AppropriationResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/assets": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "List the fixed asset register",
        "description": "Every asset of the entity by code, with cost, accumulated depreciation and net book value.\n\nAccumulated depreciation is what the ledger holds for the asset up to and including\n`as_of` (posted and pending-approval entries), so a depreciation run that has not\nhappened yet is not counted. Amounts are in the entity's functional currency. Disposed\nassets are listed too, with their status; from the disposal date on they show cost,\naccumulated depreciation and net book value 0, as in the ledger, so the columns add up\nto the balance sheet.",
        "operationId": "asset_register_v1_entities__entity__assets_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Report date, ISO 8601 (YYYY-MM-DD), e.g. `2026-09-30`.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "Report date, ISO 8601 (YYYY-MM-DD), e.g. `2026-09-30`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AssetRegisterLine"
                  },
                  "title": "Response Asset Register V1 Entities  Entity  Assets Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/audit-files": {
      "get": {
        "tags": [
          "audit files"
        ],
        "summary": "What the audit file of a year covers",
        "description": "The audit file formats that fit the entity's country (its tax audit file first: `fec` in\nFrance, `gobd` in Germany, `saft` elsewhere; then `evidence`, the audit evidence pack, in\nevery country), the dates the files of the fiscal year (or of the periods asked for) cover,\nwhether the year is closed, which covered periods are still open, how many posted entries\nthey hold, and each file's name (`file_names`); `missing` says what stops a file (`siren`).\nAnswers 422 `fiscal_year_missing` for a year the entity does not have, `audit_period_range`\nfor periods outside it, and 409 `audit_periods_open` for a part of a year with open\nperiods.",
        "operationId": "audit_file_overview_v1_entities__entity__audit_files_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. `2026`."
          },
          {
            "name": "from_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First period of a part of the year (closed periods only); default: the first.",
              "examples": [
                1
              ],
              "title": "From Period"
            },
            "description": "First period of a part of the year (closed periods only); default: the first."
          },
          {
            "name": "to_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last period of a part of the year (closed periods only); default: the last.",
              "examples": [
                12
              ],
              "title": "To Period"
            },
            "description": "Last period of a part of the year (closed periods only); default: the last."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuditFileOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/audit-files/evidence": {
      "get": {
        "tags": [
          "audit files"
        ],
        "summary": "Download the audit evidence pack",
        "description": "What an external auditor pulls from the books of an entity's fiscal year, in any\ncountry: a ZIP laid out after the AICPA Audit Data Standards (`|`-delimited UTF-8 text with\na header row, `.` as decimal separator, ISO dates) holding the journal lines with who\nentered, approved and posted each entry, a trial balance that ties to them, the chart of\naccounts, the company, the organization's users and their rights, sign-ins and security\nevents, the audit trail, the master data changes, the four-eyes approvals, the period\ncloses, the receivables and payables with what is open at the end, the deals won with their\ninvoices, the hash chain's verification, and a README describing every file and column\n(`Audit_Evidence_<entity>_<year>.zip`). Recorded in the audit trail.",
        "operationId": "evidence_file_v1_entities__entity__audit_files_evidence_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. `2026`."
          },
          {
            "name": "from_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First period of a part of the year (closed periods only); default: the first.",
              "examples": [
                1
              ],
              "title": "From Period"
            },
            "description": "First period of a part of the year (closed periods only); default: the first."
          },
          {
            "name": "to_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last period of a part of the year (closed periods only); default: the last.",
              "examples": [
                12
              ],
              "title": "To Period"
            },
            "description": "Last period of a part of the year (closed periods only); default: the last."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "A ZIP with pipe-delimited tables and README.txt.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/audit-files/fec": {
      "get": {
        "tags": [
          "audit files"
        ],
        "summary": "Download the FEC (France)",
        "description": "The fichier des écritures comptables (LPF art. L47 A, A47 A-1) of a French entity's\nfiscal year: the 18 fields, one record per line of every posted entry, the opening balances\nfirst, tab-separated, `<SIREN>FEC<closing date>.txt`. Recorded in the audit trail. Answers\n422 `audit_file_country` for an entity outside France and `siren_missing` when its French\nVAT number (where the SIREN is taken from) is missing.",
        "operationId": "fec_file_v1_entities__entity__audit_files_fec_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. `2026`."
          },
          {
            "name": "from_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First period of a part of the year (closed periods only); default: the first.",
              "examples": [
                1
              ],
              "title": "From Period"
            },
            "description": "First period of a part of the year (closed periods only); default: the first."
          },
          {
            "name": "to_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last period of a part of the year (closed periods only); default: the last.",
              "examples": [
                12
              ],
              "title": "To Period"
            },
            "description": "Last period of a part of the year (closed periods only); default: the last."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The FEC as tab-separated text in ISO-8859-15.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/audit-files/gobd": {
      "get": {
        "tags": [
          "audit files"
        ],
        "summary": "Download the GoBD audit file (Germany)",
        "description": "The data carrier for the German tax audit (AO § 147 para. 6, Z3 access) of a German\nentity's fiscal year: a ZIP with the chart of accounts and its balances, the journal of the\nposted entries, customers, vendors, the tax codes used and the open items at the end, as\nCSV, described by `index.xml` (Beschreibungsstandard 1.6) with its DTD. Recorded in the\naudit trail. Answers 422 `audit_file_country` for an entity outside Germany.",
        "operationId": "gobd_file_v1_entities__entity__audit_files_gobd_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. `2026`."
          },
          {
            "name": "from_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First period of a part of the year (closed periods only); default: the first.",
              "examples": [
                1
              ],
              "title": "From Period"
            },
            "description": "First period of a part of the year (closed periods only); default: the first."
          },
          {
            "name": "to_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last period of a part of the year (closed periods only); default: the last.",
              "examples": [
                12
              ],
              "title": "To Period"
            },
            "description": "Last period of a part of the year (closed periods only); default: the last."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "A ZIP with the CSV tables, index.xml and its DTD.",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/audit-files/saft": {
      "get": {
        "tags": [
          "audit files"
        ],
        "summary": "Download the SAF-T file (outside France and Germany)",
        "description": "The OECD Standard Audit File for Tax (version 2.0) of the fiscal year of an entity\noutside France and Germany, as XML (UTF-8, `SAF-T_<entity>_<year>.xml`): the header (company,\nVAT number, address, currency, the periods selected), the general ledger accounts with\ntheir opening and closing balances, customers and suppliers with their balances, the tax\ncodes used, and every line of every posted entry by journal, with its document, customer or\nsupplier, foreign currency amount and tax; the totals balance. Recorded in the audit trail.\nAnswers 422 `audit_file_country` for an entity in France or Germany (they get the FEC or\nthe GoBD file).",
        "operationId": "saft_file_v1_entities__entity__audit_files_saft_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. `2026`."
          },
          {
            "name": "from_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First period of a part of the year (closed periods only); default: the first.",
              "examples": [
                1
              ],
              "title": "From Period"
            },
            "description": "First period of a part of the year (closed periods only); default: the first."
          },
          {
            "name": "to_period",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last period of a part of the year (closed periods only); default: the last.",
              "examples": [
                12
              ],
              "title": "To Period"
            },
            "description": "Last period of a part of the year (closed periods only); default: the last."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The OECD SAF-T 2.0 XML in UTF-8.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/autopilot": {
      "get": {
        "tags": [
          "autopilot"
        ],
        "summary": "Get what Autopilot keeps and what waits for a person",
        "description": "Every outcome Autopilot can keep for the company: whether it is on and for whom, its state\nafter the latest pass (`on_track`, `open`, `waiting` for a person, `problem`), the items still\nopen and the steps that pass left a person, each with its place in the app; the open\nquestions the AI asked; and how much of the day's AI budget is used.",
        "operationId": "get_autopilot_v1_entities__entity__autopilot_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutopilotOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/autopilot/passes": {
      "get": {
        "tags": [
          "autopilot"
        ],
        "summary": "List Autopilot's passes",
        "description": "The company's passes, newest first: what started each, for whom it acted, what was open\nbefore and after, and how much the rules and the AI settled.",
        "operationId": "list_autopilot_passes_v1_entities__entity__autopilot_passes_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "outcome",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this outcome's, e.g. `bank_matched`.",
              "title": "Outcome"
            },
            "description": "Only this outcome's, e.g. `bank_matched`."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "At most this many, newest first.",
              "default": 50,
              "title": "Limit"
            },
            "description": "At most this many, newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PassSummary"
                  },
                  "title": "Response List Autopilot Passes V1 Entities  Entity  Autopilot Passes Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/autopilot/{outcome}": {
      "put": {
        "tags": [
          "autopilot"
        ],
        "summary": "Switch an outcome of Autopilot on or off",
        "description": "Switched on, Autopilot keeps the outcome true: a pass when something happens that gives it\nwork (a statement imported), once a day, and the first one at once. Its passes act for the\nperson who switched it on (only a person signed in can: 403 `autopilot_needs_a_person`), so\nfour eyes count what they book as that person's: a second person approves it. They never\napprove, close periods, send, pay or file.",
        "operationId": "put_autopilot_outcome_v1_entities__entity__autopilot__outcome__put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "outcome",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The outcome, e.g. `bank_matched`.",
              "examples": [
                "bank_matched"
              ],
              "title": "Outcome"
            },
            "description": "The outcome, e.g. `bank_matched`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OutcomeSettingInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OutcomeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/autopilot/{outcome}/passes": {
      "post": {
        "tags": [
          "autopilot"
        ],
        "summary": "Run a pass of an outcome now",
        "description": "Run now: check what is open, let the rules settle what they can, give the AI the items\nleft (within the day's budget), check again, and record the pass with the steps left to a\nperson. The pass acts for the caller. 409 `autopilot_pass_running` while one runs. Works\nwhether or not the outcome is switched on.",
        "operationId": "run_autopilot_pass_v1_entities__entity__autopilot__outcome__passes_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "outcome",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The outcome, e.g. `bank_matched`.",
              "examples": [
                "bank_matched"
              ],
              "title": "Outcome"
            },
            "description": "The outcome, e.g. `bank_matched`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PassInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PassOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/autopilot/{outcome}/passes/stream": {
      "post": {
        "tags": [
          "autopilot"
        ],
        "summary": "Run a pass of an outcome now, with its progress",
        "description": "`POST /v1/entities/{entity}/autopilot/{outcome}/passes`, answered as it works: the person\nsees each step as it happens. A pass already running is a 409 before anything is streamed.",
        "operationId": "run_autopilot_pass_streaming_v1_entities__entity__autopilot__outcome__passes_stream_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "outcome",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The outcome, e.g. `bank_matched`.",
              "examples": [
                "bank_matched"
              ],
              "title": "Outcome"
            },
            "description": "The outcome, e.g. `bank_matched`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PassInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "One JSON object per line: `step` for each step of the pass (the fields of a log line: `step`, `text`, ...), `working` every few seconds, then `done` with the pass (the fields of `PassOut`) or `error` (`status`, `error`).",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/bank-accounts": {
      "get": {
        "tags": [
          "swiss payments"
        ],
        "summary": "List registered bank accounts",
        "description": "IBAN, QR-IBAN, BIC and account holder registered for each GL bank account of the\nentity, by GL account code. These details are the debit account of payment files and\nthe creditor of QR-bills; a GL bank account without a registration is not listed.",
        "operationId": "list_bank_accounts_v1_entities__entity__bank_accounts_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BankAccountOut"
                  },
                  "title": "Response List Bank Accounts V1 Entities  Entity  Bank Accounts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/bank-accounts/{account}": {
      "put": {
        "tags": [
          "swiss payments"
        ],
        "summary": "Register the IBAN of a bank account",
        "description": "Register the IBAN (and QR-IBAN) and the account holder's address of a GL bank\naccount; replaces earlier details. The account must be an asset account with the bank\nrole (or a control asset account), else 422; `iban` must not be a QR-IBAN and `qr_iban`\nmust be one (422); an IBAN already registered for another account answers 409. The\napproval policy action `manage_accounts` must allow it (403 otherwise). The company's first\nbank details apply at once; a later new account, or a new IBAN or QR-IBAN, waits for a\nsecond person (`change_company_bank_details`, ADR-0043): the answer then has `status`\n`pending_approval`, the `approval_id` and the details that apply once approved, and a\nsecond change of the account answers 409 until the request is decided.",
        "operationId": "set_bank_account_v1_entities__entity__bank_accounts__account__put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "account",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code of the GL bank account in the chart of accounts, e.g. `1020`.",
              "examples": [
                "1020"
              ],
              "title": "Account"
            },
            "description": "Code of the GL bank account in the chart of accounts, e.g. `1020`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BankAccountInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankAccountOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/bank-lines": {
      "get": {
        "tags": [
          "banking"
        ],
        "summary": "List bank statement lines",
        "description": "Statement lines by status (default unmatched; ``all`` for every status).\n\nLines come in booking-date order. Amounts are signed in the line's currency: positive is\nmoney in, negative money out. `match` says how a matched or ignored line was settled.\nAn unmatched line gives the day a match or posting books it on by default (`posting_date`):\nits booking date, or when that is in a closed period (`closed_period`) the first day of the\nnext open period.",
        "operationId": "list_lines_v1_entities__entity__bank_lines_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "all",
                    "ignored",
                    "matched",
                    "unmatched"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Line status: `unmatched` (default), `matched`, `ignored` or `all`.",
              "default": "unmatched",
              "title": "Status"
            },
            "description": "Line status: `unmatched` (default), `matched`, `ignored` or `all`."
          },
          {
            "name": "statement",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the lines of this statement (id from the statement list).",
              "title": "Statement"
            },
            "description": "Only the lines of this statement (id from the statement list)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BankLineOut"
                  },
                  "title": "Response List Lines V1 Entities  Entity  Bank Lines Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/bank-reconciliation": {
      "get": {
        "tags": [
          "banking"
        ],
        "summary": "Reconcile a bank account",
        "description": "The bank account's statement balance on the date against its ledger balance, and the\nitems that explain the difference.\n\nBank items are statement lines up to the date that the ledger does not show by then:\n`unmatched`, `ignored`, `waiting_for_approval` (the booking waits for a second person) or\n`booked_later`. Ledger items are posted entries on the account from the first statement's\nstart (`since`) to the date that no statement line up to the date books, such as a payment\nrecorded as executed that a later statement shows (one the bank has not executed yet is in\ntransit, ADR-0060, not on the account); an entry and its reversal in that range cancel out.\n`unexplained` is the difference less the opening difference, less the bank items, plus the\nledger items: zero when everything is accounted for. `done` is the record when a person\nmarked this account and date reconciled.",
        "operationId": "reconciliation_v1_entities__entity__bank_reconciliation_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "account",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "GL bank account code, e.g. `1020`. Default: the main bank account.",
              "title": "Account"
            },
            "description": "GL bank account code, e.g. `1020`. Default: the main bank account."
          },
          {
            "name": "on",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Statement date. Default: the end date of the account's latest statement, else today.",
              "title": "On"
            },
            "description": "Statement date. Default: the end date of the account's latest statement, else today."
          },
          {
            "name": "statement_balance",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The closing balance on the bank's statement, used only when no imported statement for the date carries one (a CSV file).",
              "title": "Statement Balance"
            },
            "description": "The closing balance on the bank's statement, used only when no imported statement for the date carries one (a CSV file)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BankReconciliationView"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/bank-reconciliations": {
      "get": {
        "tags": [
          "banking"
        ],
        "summary": "List bank reconciliations",
        "description": "The reconciliations people marked done, latest statement date first. A record that was\nreset stays in the list with `reset_at`, `reset_by` and `reset_reason`; only one record per\naccount and date stands.",
        "operationId": "history_v1_entities__entity__bank_reconciliations_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "account",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this bank account, e.g. `1020`.",
              "title": "Account"
            },
            "description": "Only this bank account, e.g. `1020`."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "At most this many (up to 1000).",
              "default": 100,
              "title": "Limit"
            },
            "description": "At most this many (up to 1000)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ReconciliationDone"
                  },
                  "title": "Response History V1 Entities  Entity  Bank Reconciliations Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Mark a bank account reconciled",
        "description": "Record that the account is reconciled on the statement date: who, when, and the balances\nand item totals as they are now. The record changes only by a reset.\n\nOnly a person does it (403 for an agent). Refused: 409 `reconciliation_done` when the account\nand date were marked before (a controller resets that record first, `POST\n.../bank-reconciliations/{reconciliation_id}/reset`); 422 `reconciliation_in_future` for a\ndate after today, `statement_balance_missing` when no imported statement for the date carries\na closing balance and none is given, `statement_balance_differs` when the given balance is\nnot the statement's, and `reconciliation_unexplained` (`amount`, `currency`) when part of\nthe difference is unexplained and there is no `note`. Safe to repeat without an\nIdempotency-Key: a second request is refused with 409.",
        "operationId": "mark_done_v1_entities__entity__bank_reconciliations_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReconcileInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReconciliationDone"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/bank-reconciliations/{reconciliation_id}/reset": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Reset a bank reconciliation",
        "description": "Take back a reconciliation marked done, for instance one made with a wrong bank balance,\nwith a `reason` (required, at most 500 characters). The record stays, with `reset_at`,\n`reset_by` and `reset_reason`, and the reset is in the audit trail\n(`bank.reconcile_reset`); the account and date can then be reconciled again.\n\nWhoever may reopen a period may do it: the approve scope and the approval policy's\n`reopen_period` action (agents are denied, 403). Refused: 404 when the record is not one of\nthe entity; 409 `reconciliation_reset_already` when it was reset before, and\n`reconciliation_later` (`later`) when the account was reconciled on a later date that still\nstands: reset the latest first. Safe to repeat without an Idempotency-Key: a second request\nis refused with 409.",
        "operationId": "reset_v1_entities__entity__bank_reconciliations__reconciliation_id__reset_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "reconciliation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Reconciliation id (`GET /v1/entities/{entity}/bank-reconciliations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Reconciliation Id"
            },
            "description": "Reconciliation id (`GET /v1/entities/{entity}/bank-reconciliations`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReconciliationDone"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/bank-statements": {
      "get": {
        "tags": [
          "banking"
        ],
        "summary": "List bank statements",
        "description": "Imported statements and notifications, newest first, with their lines by status.\n\nEach statement gives its account, period, opening and closing balance as reported by the\nbank, and how many of its lines are unmatched, matched or ignored.",
        "operationId": "list_statements_v1_entities__entity__bank_statements_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "description": "Maximum number of statements to return (up to 1000).",
              "examples": [
                100
              ],
              "default": 100,
              "title": "Limit"
            },
            "description": "Maximum number of statements to return (up to 1000)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StatementOut"
                  },
                  "title": "Response List Statements V1 Entities  Entity  Bank Statements Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Import a bank statement",
        "description": "Import a camt.053 statement, a camt.054 notification (ISO 20022, SPS), an MT940\nstatement or a CSV file.\n\nSend a multipart form: the file in field `file` and `format` set to `camt053` (default),\n`camt054`, `mt940` or `csv`; for CSV also `csv_mapping`. An MT940 statement whose account\nline holds no IBAN (a German bank code and account number) goes to `account`, else the\nentity's bank account; one whose transactions do not add up from its opening to its\nclosing balance is refused (`mt940_balance_mismatch`). One file can hold several statements, so\nthe response lists one result each (lines imported, skipped as duplicates by bank\nreference, matched and still unmatched). Credits are matched to open invoices by their QR\nor ISO 11649 reference first, then by reference text, amount and counterparty; a line\nthat executes a payment already booked (a payment run's) is linked to it by its number as\nend-to-end id or in the text, and never booked again; the matches create payments that\nfollow the approval policy. A CSV statement is named after its account and dates, e.g.\n`CSV 1020 01.09.2026-30.09.2026`. Refused: 409 when the statement reference or its\ntransactions were imported before; 422 for a file over 10 MB, an unreadable file, a\ncurrency that differs from the bank account's, or an account that is not a bank account.",
        "operationId": "import_statement_v1_entities__entity__bank_statements_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_import_statement_v1_entities__entity__bank_statements_post"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ImportResult"
                  },
                  "title": "Response Import Statement V1 Entities  Entity  Bank Statements Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/bank-statements/preview": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Preview a CSV bank file",
        "description": "Read a CSV bank file as the import would, without storing anything.\n\nWithout `csv_mapping` the mapping is guessed: the delimiter (`;`, `,` or tab), the columns\nby their header names in German, French, Italian or English (a signed amount, or separate\ncredit and debit columns), the date format and a decimal comma, from the values. The\nanswer has the file's columns, the `mapping` used (send it with the import), the\ntransactions read (the first 200, with `count` of all), their dates and sums, how many the\naccount already holds (`duplicates`, which the import skips) and the statement's name.\nA file the mapping cannot read is not refused: `problem` says why (a missing column, a\nline that cannot be read), with the code the import would refuse it with. Refused: 422 for\na file over 10 MB, a `csv_mapping` that is not a mapping, or an account that is not a bank\naccount.",
        "operationId": "preview_statement_v1_entities__entity__bank_statements_preview_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_preview_statement_v1_entities__entity__bank_statements_preview_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CsvPreview"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/book-tax-differences": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Get book-tax differences",
        "description": "Carrying amount vs tax base per asset and tax book at a period end, with the\ndeferred tax (IAS 12) for the book that carries it.\n\nCovers assets in service by the period end that are in a tax book. A positive temporary\ndifference is taxable (a liability), a negative one deductible (an asset). `totals` per\nbook show, for the book that carries deferred tax, the liability and asset now, what is\nposted so far and the `movement` the next deferred-tax run would post. Amounts are in\nthe entity's functional currency. Refused with 404 when the period does not exist.",
        "operationId": "book_tax_differences_v1_entities__entity__book_tax_differences_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "Fiscal year of the period.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "Fiscal year of the period."
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "Period number within the fiscal year (1-based, adjustment periods follow the regular ones).",
              "examples": [
                9
              ],
              "title": "Period"
            },
            "description": "Period number within the fiscal year (1-based, adjustment periods follow the regular ones)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DifferenceReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/brand": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "Read a company's brand",
        "description": "The company's logo, brand and accent colours and the theme of the app, with the contrast\nof the colours in use against white. A company that set nothing has the product's look: no\nlogo, the deep teal, the light theme.",
        "operationId": "get_brand_v1_entities__entity__brand_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "setup"
        ],
        "summary": "Change a company's colours",
        "description": "Change the theme (`light`, `dark`, `system`), the brand colour or the accent colour; only\nthe fields sent change, and `null` sets a colour back to the default. The brand colour is the\napp's buttons and links and the title of every invoice, quote and reminder: it must reach\n4.5:1 against white (422 `brand_colour_contrast`, with the ratio). The accent colour draws\nthe rules of the documents and the band of the e-mails: 3:1 (422 `brand_accent_contrast`).\n422 `brand_colour` for what is not a colour. Audited as `brand.update`.",
        "operationId": "update_brand_v1_entities__entity__brand_patch",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BrandUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/brand/logo": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "Download a company's logo",
        "description": "The stored PNG. Its address in `GET /v1/entities/{entity}/brand` changes with the file, so\na browser keeps it for a day.",
        "operationId": "get_logo_v1_entities__entity__brand_logo_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The logo as a PNG.",
            "content": {
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "404": {
            "description": "`brand_no_logo`: the company has no logo."
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "setup"
        ],
        "summary": "Upload a company's logo",
        "description": "Send `multipart/form-data` with the image in the field `file`. It is read by its bytes,\nreduced to at most 1200 x 480 pixels keeping its proportions and kept as a PNG without\nmetadata; it replaces the company's logo on the app's top bar, on its PDFs, its e-mails to\ncustomers, the customer's page of a quote and its website forms. 422 `brand_logo_empty`,\n`brand_logo_too_large`, `brand_logo_svg` or `brand_logo_invalid`. Audited as `brand.logo`\nwith the PNG's SHA-256; sending the same file again changes nothing that shows.",
        "operationId": "upload_logo_v1_entities__entity__brand_logo_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_upload_logo_v1_entities__entity__brand_logo_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "setup"
        ],
        "summary": "Remove a company's logo",
        "description": "The company's documents and pages show its name alone again. Audited as\n`brand.logo_remove`; removing a logo that is not there changes nothing.",
        "operationId": "delete_logo_v1_entities__entity__brand_logo_delete",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/cash-forecast": {
      "get": {
        "tags": [
          "cash-forecast"
        ],
        "summary": "Forecast cash for 13 weeks",
        "description": "Today's cash and what comes in and goes out in each of the 13 weeks from this week's\nMonday: open invoices and bills at the day each customer usually pays (and each vendor is\nusually paid) over the last 12 months, payments recorded but not posted yet, the invoices\nrecurring invoices and subscriptions will make, and recurring journals on a cash account.\nWith the lowest cash at a week's end, every line behind the weeks, and what changed since\nthe forecast kept in an earlier week (kept once a week by the scheduled jobs). Nothing is\nposted.",
        "operationId": "get_cash_forecast_v1_entities__entity__cash_forecast_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Make it as on this day; default the company's today.",
              "title": "As Of"
            },
            "description": "Make it as on this day; default the company's today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CashForecastOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/chain-verification": {
      "get": {
        "tags": [
          "audit"
        ],
        "summary": "Chain Verification",
        "description": "Recompute the hash chain of all posted entries of the entity to detect tampering.\nEvery posted entry holds a hash of its content and of its predecessor. The answer is\n`valid` with the number of `entries`, or not valid with the number of the first entry\nthat breaks the chain (`first_invalid`) and why (`reason`: a gap in the sequence, a wrong\nprevious hash, or changed content).",
        "operationId": "chain_verification_v1_entities__entity__chain_verification_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChainCheck"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/close-schedule": {
      "get": {
        "tags": [
          "close tracker"
        ],
        "summary": "Get the close calendar of an entity",
        "description": "Who owns the entity's month-end close and the working day after the period end each step\nis due on (the defaults until the entity sets its own: `configured` is false). Read-only.",
        "operationId": "get_close_schedule_v1_entities__entity__close_schedule_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "close tracker"
        ],
        "summary": "Set the close calendar of an entity",
        "description": "Set the close owner, the working days of the steps and which steps the **scheduled close\njob** runs for the entity (`automated_steps`: `recurring_invoices`, `bank_matching`,\n`depreciation`, `fx_revaluation`, `deferred_tax`, `checklist`, `close_review` and\n`forecast_roll`; empty, the default, leaves the entity to people); what the body leaves out\nkeeps its value. The job runs once a day, as the organization's system actor, and never\napproves or closes anything; taking a step out stops it at the next run. **A person's** act:\nthe policy action `manage_close` denies agents (403, naming the rule). 422 for an owner who is\nnot a person of the organization, a day outside 0 to 30, or a step the job does not run.",
        "operationId": "set_close_schedule_v1_entities__entity__close_schedule_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ScheduleOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/close-tasks": {
      "get": {
        "tags": [
          "close tracker"
        ],
        "summary": "List the close tasks of an entity",
        "description": "The entity's own month-end tasks, by the working day they are due on. Read-only.",
        "operationId": "list_close_tasks_v1_entities__entity__close_tasks_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "include_inactive",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Also the tasks that are no longer part of the close.",
              "default": false,
              "title": "Include Inactive"
            },
            "description": "Also the tasks that are no longer part of the close."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many tasks, the earliest due first.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many tasks, the earliest due first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TaskOut"
                  },
                  "title": "Response List Close Tasks V1 Entities  Entity  Close Tasks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "close tracker"
        ],
        "summary": "Add a close task",
        "description": "A task of every month end of the entity: what, who and on which working day after the\nperiod end. With `check_id` the task is decided by that close check (done when it passes or\ndoes not apply), so nobody marks it done by hand. **A person's** act (`manage_close`). 422 for\nan unknown check or an owner outside the organization. Needs an `Idempotency-Key`.",
        "operationId": "create_close_task_v1_entities__entity__close_tasks_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/credit-exposure": {
      "get": {
        "tags": [
          "parties"
        ],
        "summary": "Get the credit exposure of customers with a credit limit",
        "description": "Every customer of the company with a credit limit, those over it first: its limit, what\nit owes (`receivables`: open invoices less open credit notes and payments on account), its\ninvoices waiting for approval, what is left to invoice on its open sales orders (VAT\nincluded), the total (`exposure`), the credit still `available` and whether it is over the\nlimit. All in the customer's currency: an amount in another currency is converted at today's\nECB rate (today where the company is). An invoice that would take a customer above its limit\nwaits for a second person when it is submitted; a sales order is not confirmed. Read-only;\n404 for an unknown entity.",
        "operationId": "get_credit_exposure_v1_entities__entity__credit_exposure_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "json"
              ],
              "type": "string",
              "description": "`json` (default) or `csv`: one row per customer with the columns `customer`, `name`, `currency`, `credit_limit`, `receivables`, `pending_invoices`, `open_orders`, `exposure`, `available`, `over_limit` and `note`, meaning what the JSON fields of the same names mean.",
              "default": "json",
              "title": "Format"
            },
            "description": "`json` (default) or `csv`: one row per customer with the columns `customer`, `name`, `currency`, `credit_limit`, `receivables`, `pending_invoices`, `open_orders`, `exposure`, `available`, `over_limit` and `note`, meaning what the JSON fields of the same names mean."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`csv`: `true` sends the file as an attachment; `false` inline.",
              "default": false,
              "title": "Download"
            },
            "description": "`csv`: `true` sends the file as an attachment; `false` inline."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "JSON (the report) or CSV (one row per customer).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditExposure"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/customers/{party}/activity": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "Get a customer's activity statement: invoices, credit notes and payments",
        "description": "What the customer owes us and how it came about: per currency, the opening balance on\n`start`, every invoice, credit note and payment received up to `end` (with a payment's\nreversal and a later application of an amount on account or a credit note) with the running\nbalance, and the closing balance, in the currency of each movement. `open_items` are the\nitems still open at the end of `end`, as on the open-items statement of that day\n(`GET .../statement?as_of=`); `closing_functional` is the customer's balance on the\nreceivables control account in the functional currency, the statement's\n`reconciliation.control_balance`.\n\nIt is read from the customer's own lines on the receivables control account, so the closing\nbalance is the one in the books. Read-only: it posts nothing, it is not archived and it is not\na request for payment. 404 for an unknown entity or customer (a vendor is not a customer: its\nstatement is `GET .../vendors/{party}/statement`), 422 when `start` is after `end`.",
        "operationId": "get_customer_activity_v1_entities__entity__customers__party__activity_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The first day of the period, ISO 8601. What the customer owed before it is the opening balance.",
              "examples": [
                "2026-07-01"
              ],
              "title": "Start"
            },
            "description": "The first day of the period, ISO 8601. What the customer owed before it is the opening balance."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The last day of the period, ISO 8601, not before `start`.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "The last day of the period, ISO 8601, not before `start`."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "json",
                "pdf"
              ],
              "type": "string",
              "description": "`json` (default): the statement; `csv`: one row per movement with the opening and closing balance of each currency; `pdf`: an A4 PDF in the customer's language (`language` chooses another), rendered now and not stored.",
              "default": "json",
              "title": "Format"
            },
            "description": "`json` (default): the statement; `csv`: one row per movement with the opening and closing balance of each currency; `pdf`: an A4 PDF in the customer's language (`language` chooses another), rendered now and not stored."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "it",
                    "sv"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`format=pdf` only: `de`, `fr`, `it`, `en` or `sv`. Omitted: the customer's language, else the language of its country.",
              "title": "Language"
            },
            "description": "`format=pdf` only: `de`, `fr`, `it`, `en` or `sv`. Omitted: the customer's language, else the language of its country."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`csv` and `pdf`: `true` sends the file as an attachment.",
              "default": false,
              "title": "Download"
            },
            "description": "`csv` and `pdf`: `true` sends the file as an attachment."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "JSON (the statement), CSV (its movements) or the PDF in the customer's language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerActivity"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/customers/{party}/mandates": {
      "get": {
        "tags": [
          "direct debits"
        ],
        "summary": "List a customer's SEPA mandates",
        "description": "The customer's SEPA direct debit mandates, newest signature first, each with its status\n(`pending_approval`, `active`, `rejected`, `revoked`, `expired` after 36 months without a\ncollection, `used` for a one-off mandate collected from), the sequence type of its next\ncollection and any change waiting for a second person. 404 for an unknown customer.",
        "operationId": "list_mandates_v1_entities__entity__customers__party__mandates_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MandateOut"
                  },
                  "title": "Response List Mandates V1 Entities  Entity  Customers  Party  Mandates Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "direct debits"
        ],
        "summary": "Record a customer's SEPA mandate",
        "description": "Record a SEPA direct debit mandate the customer signed (CORE or B2B, recurring or\none-off). It waits for a second person's approval (`POST /v1/approvals/{id}/approve`) before\nanything is collected under it; agents cannot record mandates (403). Refuses with 409 when the\nreference is already used in the entity (in any case), 422 for an invalid reference or IBAN,\nan IBAN outside SEPA, or a signature date after today.",
        "operationId": "create_mandate_v1_entities__entity__customers__party__mandates_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MandateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MandateOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/customers/{party}/price-lists": {
      "get": {
        "tags": [
          "price lists"
        ],
        "summary": "List a customer's price lists",
        "description": "The price list the customer takes in each currency, by currency (at most one per\ncurrency). 404 for an unknown customer. Read-only.",
        "operationId": "list_customer_price_lists_v1_entities__entity__customers__party__price_lists_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CustomerPriceListOut"
                  },
                  "title": "Response List Customer Price Lists V1 Entities  Entity  Customers  Party  Price Lists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/customers/{party}/price-lists/{currency}": {
      "put": {
        "tags": [
          "price lists"
        ],
        "summary": "Give a customer a price list",
        "description": "The customer takes the list in the currency, in place of the one it had in it (audited\nwith the previous list). Safe to repeat: giving it the list it has changes nothing. 422 when\nthe list is in another currency; 409 when it is inactive; 404 for an unknown customer or\nlist.",
        "operationId": "set_customer_price_list_v1_entities__entity__customers__party__price_lists__currency__put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "currency",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{3}$",
              "description": "ISO 4217 code, e.g. `CHF`.",
              "examples": [
                "CHF"
              ],
              "title": "Currency"
            },
            "description": "ISO 4217 code, e.g. `CHF`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerPriceListSet"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CustomerPriceListOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "price lists"
        ],
        "summary": "Take a customer's price list away",
        "description": "The customer takes no price list in the currency any more: its lines propose the list\nprice again (audited with the previous list). Safe to repeat. 404 for an unknown customer.",
        "operationId": "remove_customer_price_list_v1_entities__entity__customers__party__price_lists__currency__delete",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "currency",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{3}$",
              "description": "ISO 4217 code, e.g. `CHF`.",
              "examples": [
                "CHF"
              ],
              "title": "Currency"
            },
            "description": "ISO 4217 code, e.g. `CHF`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/customers/{party}/reminders": {
      "post": {
        "tags": [
          "dunning"
        ],
        "summary": "Make a reminder letter to a customer",
        "description": "Make the letter to the customer in `currency` (omitted: the one currency it is due a\nreminder in, its own of several), dated today in the entity's country with today's amounts:\nit names the customer's invoices in that currency that are due a reminder (all of them, or\n`documents`), at the highest level they reached (each invoice's own when\nthey differ), and asks for their open amount within 10 days. The PDF is in the\ncustomer's language (`language` chooses another) and is archived with its SHA-256 (the\ndocument archive, kind `dunning_notice`); the letter never changes. Then send it\n(`POST /v1/reminders/{id}/send`) or record how it was handed over\n(`POST /v1/reminders/{id}/mark-sent`): the next level counts from that day.\n\nThe letter deducts what the customer has to its credit in the currency and not yet applied\n(credit notes with something open, receipts' amounts on account), as far as no letter still\nstanding deducted it already: the letters together never ask for less than is owed.\n\nA person makes it: the policy action `release_dunning` is denied to agents, and an agent key\nanswers 403 whatever the policy says. It claims no fee and no interest and posts nothing.\n409 `no_reminder_due` when nothing is due, 409 `reminder_covered_by_credits` when the\ncustomer's credits cover the invoices asked for, 422 `reminder_not_due` for an invoice asked\nfor that is not, 422 `reminder_currency_needed` when no currency is named and the customer\nis due reminders in several, none its own, 422 `reminder_in_future` or `reminder_backdated`\nfor an `as_of` other than today. Needs an `Idempotency-Key`.",
        "operationId": "create_reminder_v1_entities__entity__customers__party__reminders_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReminderCreateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/customers/{party}/sales-tax": {
      "get": {
        "tags": [
          "sales tax"
        ],
        "summary": "Get a customer's tax area and exemption",
        "description": "The customer's state, tax area and exemption certificate, and whether it is valid today.",
        "operationId": "get_customer_v1_entities__entity__customers__party__sales_tax_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxCustomerOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "sales tax"
        ],
        "summary": "Set a customer's tax area and exemption",
        "description": "Replaces the customer's tax area (one of its state) and exemption certificate: with a\ncertificate valid on a document's day, the customer is charged no sales tax. Needs the policy\naction `change_party_details`, which agents are always denied (403).",
        "operationId": "put_customer_v1_entities__entity__customers__party__sales_tax_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxCustomerInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxCustomerOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/customers/{party}/statement": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "Get a customer's statement of account",
        "description": "The open items of one customer on a day: what the customer still owes us then.\n\nIt is the aging report restricted to the customer, from the same positions and rules:\nallocations (payments, credit notes, a cash discount taken) count from the day they took\neffect, so those dated after `as_of` do not; a part payment lowers the open amount of its\ninvoice; a credit note is a negative item; a payment waiting for approval reserves its amount\n(`reserved`). `items` are oldest due date first, `balances` give the balance and the open\namount per age band for each currency, and `totals_functional` the same in the entity's\nfunctional currency.\n\n**It ties to the ledger.** `reconciliation` compares `totals_functional.total` with the\ncustomer's own lines on the receivables control account up to `as_of`: they are equal, apart\nfrom the period-end revaluation postings that sit on the control account (`unrealised_fx`,\nnamed); `unexplained` is zero, and anything else would be a posting no document carries.\n`issued` lists the statements of this day that were archived.\n\nA statement is read-only: it posts nothing, and it is not a request for payment. 404 for an\nunknown entity or customer (a vendor is not a customer: its statement is\n`GET .../vendors/{party}/statement`). Interest accrued but not yet charged comes in a later\nslice of ADR-0028.",
        "operationId": "get_statement_v1_entities__entity__customers__party__statement_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The day the statement is as of, ISO 8601, e.g. `2026-09-30`. Allocations dated after it, and documents dated after it, are not counted. Required: a statement is evidence of a day, so the day is always named.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The day the statement is as of, ISO 8601, e.g. `2026-09-30`. Allocations dated after it, and documents dated after it, are not counted. Required: a statement is evidence of a day, so the day is always named."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "json",
                "pdf"
              ],
              "type": "string",
              "description": "`json` (default): the statement; `csv`: one row per open item; `pdf`: the statement as an A4 PDF in the customer's language (`language` chooses another). For `pdf`, the archived file is returned when the statement of this customer, day and language was issued (`POST .../statement/issue`; the header `X-Statement-Archived: true` says so), otherwise the PDF is rendered now and nothing is stored.",
              "default": "json",
              "title": "Format"
            },
            "description": "`json` (default): the statement; `csv`: one row per open item; `pdf`: the statement as an A4 PDF in the customer's language (`language` chooses another). For `pdf`, the archived file is returned when the statement of this customer, day and language was issued (`POST .../statement/issue`; the header `X-Statement-Archived: true` says so), otherwise the PDF is rendered now and nothing is stored."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "it",
                    "sv"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`format=pdf` only: `de`, `fr`, `it`, `en` or `sv`. Omitted: the customer's language, else the language of its country. Another language is another file.",
              "title": "Language"
            },
            "description": "`format=pdf` only: `de`, `fr`, `it`, `en` or `sv`. Omitted: the customer's language, else the language of its country. Another language is another file."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`csv` and `pdf`: `true` sends the file as an attachment; `false` (default) inline.",
              "default": false,
              "title": "Download"
            },
            "description": "`csv` and `pdf`: `true` sends the file as an attachment; `false` (default) inline."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "JSON (the statement), CSV (its open items) or the PDF in the customer's language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Statement"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/customers/{party}/statement/issue": {
      "post": {
        "tags": [
          "dunning"
        ],
        "summary": "Issue a customer's statement: archive its PDF",
        "description": "Store the PDF of the customer's statement on `as_of` in the document archive, so that\nwhat the customer was told on that day can be shown later.\n\nThe exact bytes are kept with their SHA-256 (`document.kind` `customer_statement`, the\ncustomer, the day and the language in its metadata; the audit event is `statement.issue`).\nThere is one file per customer, day and language: a second issue returns the first file with\n`created` false, and nothing is rewritten (the archive wins, as for invoices). The statement\nis deterministic for a day: the same ledger gives the same bytes. Download the file with\n`GET .../statement?format=pdf` and the same `as_of` and `language`.\n\nOnly a person issues, and it needs the `post` scope: an agent key answers 403 whatever its\nscopes. 422 for an `as_of` after today (it would not be what the customer was told), 404 for\nan unknown entity or customer. A statement posts nothing and is not a request for payment.\nNeeds an `Idempotency-Key`.",
        "operationId": "issue_statement_v1_entities__entity__customers__party__statement_issue_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer code, e.g. `C-DE`, or its id. A vendor is not a customer: its statement is `GET .../vendors/{party}/statement`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatementIssueInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatementIssued"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/delivered-not-invoiced": {
      "get": {
        "tags": [
          "delivery notes"
        ],
        "summary": "Delivered, not invoiced",
        "description": "Every line of a posted delivery note with goods delivered and not yet invoiced (less what\ncame back, invoiced net of credit notes), oldest first, with what is left at the cost it left\nwith: the revenue still to invoice.",
        "operationId": "delivered_not_invoiced_v1_entities__entity__delivered_not_invoiced_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "customer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's (code or id).",
              "title": "Customer"
            },
            "description": "Only this customer's (code or id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UninvoicedLine"
                  },
                  "title": "Response Delivered Not Invoiced V1 Entities  Entity  Delivered Not Invoiced Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/depreciation-books": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "List depreciation books",
        "description": "The accounting book (BOOK) and the entity's tax books.",
        "operationId": "list_depreciation_books_v1_entities__entity__depreciation_books_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BookOut"
                  },
                  "title": "Response List Depreciation Books V1 Entities  Entity  Depreciation Books Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Create a tax depreciation book",
        "description": "Add a tax book (e.g. TAX-CH for CH ESTV rates), optionally carrying deferred tax.\n\nA tax book holds a tax schedule per asset and posts nothing itself. At most one book per\nentity can carry deferred tax (IAS 12); it then needs `tax_rate_percent` and the\ndeferred tax liability, asset and expense accounts (named or found by role). Refused:\n403 without the right to manage accounts; 409 when the code exists or another book\nalready carries deferred tax; 422 for the reserved codes `BOOK` and `MEMO`, deferred tax\nwithout a rate, or a deferred-tax account that is missing.",
        "operationId": "create_depreciation_book_v1_entities__entity__depreciation_books_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/depreciation-books/{code}": {
      "patch": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Update a tax depreciation book",
        "description": "Rename a tax book or change its tax rate; the next deferred-tax run remeasures.\n\nOnly the fields sent are changed. Refused: 403 without the right to manage accounts;\n404 when the book does not exist in the entity (the accounting book `BOOK` cannot be\nchanged).",
        "operationId": "update_depreciation_book_v1_entities__entity__depreciation_books__code__patch",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "code",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code of the tax book, e.g. `TAX-CH`.",
              "examples": [
                "TAX-CH"
              ],
              "title": "Code"
            },
            "description": "Code of the tax book, e.g. `TAX-CH`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/direct-debit-proposals": {
      "post": {
        "tags": [
          "direct debits"
        ],
        "summary": "Suggest invoices to collect by direct debit",
        "description": "Open posted EUR sales invoices of customers with a SEPA mandate that are due by the\ncollection date, or whose cash discount is still open on it (collected less the discount),\nwith the mandate and sequence type each is collected under. Nothing is stored; confirm the\nreviewed lines with `POST /v1/entities/{entity}/direct-debit-runs`. `skipped` lists the\ninvoices of such customers that cannot be collected on the date, and why (no usable mandate,\nthe pre-notification too short, not due yet); `problems` what stops collecting at all (no EUR\nbank account with a SEPA creditor identifier, no payments-in-transit account).",
        "operationId": "propose_collections_v1_entities__entity__direct_debit_proposals_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CollectionCriteria"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionProposal"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/direct-debit-runs": {
      "post": {
        "tags": [
          "direct debits"
        ],
        "summary": "Collect the invoices of a proposal",
        "description": "Create the receipts of a reviewed proposal, all or none: one per mandate, dated the\ncollection date and booked on the payments-in-transit account until the bank statement shows\nthe money, each through the approval policy. 422 when an invoice is not a posted EUR sales\ninvoice, is listed twice, its customer has no usable mandate or its pre-notification is too\nshort. Release them with `POST /v1/direct-debit-exports`.",
        "operationId": "run_collections_v1_entities__entity__direct_debit_runs_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CollectionRunInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CollectionRunResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/direct-debits": {
      "get": {
        "tags": [
          "direct debits"
        ],
        "summary": "List direct debit collections",
        "description": "The receipts collected by direct debit, newest first (at most 200): mandate, scheme,\nsequence type, collection date, whether the bank booked them, the file they were sent in, and\n`problems`, what stops releasing one now.",
        "operationId": "list_collections_v1_entities__entity__direct_debits_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "sent",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`false`: not yet in a file; `true`: sent. Default both.",
              "title": "Sent"
            },
            "description": "`false`: not yet in a file; `true`: sent. Default both."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CollectionRow"
                  },
                  "title": "Response List Collections V1 Entities  Entity  Direct Debits Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/expense-policy": {
      "get": {
        "tags": [
          "expenses"
        ],
        "summary": "Get the expense policy",
        "description": "What the AI reviewer holds an expense for: the limit per receipt and per expense\naccount, the oldest receipt taken and the amount above which a project is named. A company\nthat has not set its own has the defaults (`default` true).",
        "operationId": "get_expense_policy_v1_entities__entity__expense_policy_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "expenses"
        ],
        "summary": "Set the expense policy",
        "description": "Set the company's expense policy (administrators). Audited with what it was.",
        "operationId": "set_expense_policy_v1_entities__entity__expense_policy_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PolicyUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PolicyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/fiscal-years": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "List Fiscal Years",
        "description": "The entity's fiscal years, oldest first, each with its calendar, its first and last day,\nits periods (regular periods, then adjustment periods) and its year-end close (`close`: status,\nresult and what is left to appropriate). `unappropriated=true` keeps the years whose general\nmeeting is overdue while part of the result is unappropriated.",
        "operationId": "list_fiscal_years_v1_entities__entity__fiscal_years_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "unappropriated",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only the years whose result is still unappropriated when the general meeting is overdue (a Swiss entity, six months after the year end, Art. 699 para. 2 OR): the list the Role Center cue counts.",
              "default": false,
              "title": "Unappropriated"
            },
            "description": "Only the years whose result is still unappropriated when the general meeting is overdue (a Swiss entity, six months after the year end, Art. 699 para. 2 OR): the list the Role Center cue counts."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day the overdue rule is judged on, ISO 8601; default: today where the entity is.",
              "examples": [
                "2027-07-15"
              ],
              "title": "As Of"
            },
            "description": "The day the overdue rule is judged on, ISO 8601; default: today where the entity is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FiscalYearOut"
                  },
                  "title": "Response List Fiscal Years V1 Entities  Entity  Fiscal Years Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "setup"
        ],
        "summary": "Open a fiscal year",
        "description": "Open a fiscal year by creating its periods: monthly, 4-4-5 / 4-5-4 / 5-4-4, or 13\nfour-week periods, optionally with one or two adjustment periods on the last day.\n\nA year directly follows the last year (it starts the day after it ends) or directly\nprecedes the first. Without `calendar` the year uses the calendar of the latest earlier\nyear, else twelve calendar months. Returns the new periods, all `open`. Refused with 409\nwhen the year exists or overlaps another, or when a year would be missing in between\n(`fiscal_year_gap`, with `missing`: the year to open first), 422 when the calendar does not\ngive a year of about 12 months.",
        "operationId": "open_fiscal_year_v1_entities__entity__fiscal_years_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FiscalYearRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PeriodOut"
                  },
                  "title": "Response Open Fiscal Year V1 Entities  Entity  Fiscal Years Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/fiscal-years/{year}/close": {
      "get": {
        "tags": [
          "year-end close"
        ],
        "summary": "Get the year-end close of a year",
        "description": "The year close that holds the fiscal year (`pending` or `closed`), else the newest one\n(`reopened` or `cancelled`), with its result, what is appropriated and what is left\n(`remainder`), the closing entry and the approval waiting for a second person, and the\nresolutions booked against the result. 404 when the year was never proposed.",
        "operationId": "get_close_v1_entities__entity__fiscal_years__year__close_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, the calendar year it ends in, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "The fiscal year, the calendar year it ends in, e.g. `2026`."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day `appropriation_overdue` is judged on, ISO 8601; default: today.",
              "examples": [
                "2027-07-15"
              ],
              "title": "As Of"
            },
            "description": "The day `appropriation_overdue` is judged on, ISO 8601; default: today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/YearCloseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "year-end close"
        ],
        "summary": "Propose the year-end close",
        "description": "Close the fiscal year: write the closing entry and submit it through the approval policy.\n\nA human proposes it (the policy action `close_fiscal_year` denies agents). It is refused with\n409 `year_close_blocked`, listing `blockers`, while the year holds a draft entry, an entry or a\ndocument waiting for approval, or while its last period is not open, and with 409\n`role_missing` while the entity has no account with the role `annual_result`. Otherwise the\nyear is **locked at once**: from the proposal until the close is cancelled or reopened, no\nother entry is posted into the fiscal year, whatever its source (a payment, the FX\nrevaluation and a bank posting wait). By default a second person approves the entry\n(`POST /v1/approvals/{approval_id}/approve`, `close_entries_need_a_second_person`); the\napproval computes the totals again and refuses with 409 `year_changed` if they differ from the\nproposal's. The response's `submit` says whether the entry is `posted` or waits.\nNeeds an `Idempotency-Key`.",
        "operationId": "propose_close_v1_entities__entity__fiscal_years__year__close_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, the calendar year it ends in, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "The fiscal year, the calendar year it ends in, e.g. `2026`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CloseResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/fiscal-years/{year}/close-preview": {
      "get": {
        "tags": [
          "year-end close"
        ],
        "summary": "Preview the year-end close",
        "description": "What closing the fiscal year would post, computed now, and what stands in the way.\n\nThe closing entry brings every profit and loss account of the year to zero against the account\nwith the role `annual_result`; `result` is the profit (positive) or loss, `lines` the entry,\n`totals_digest` the fingerprint of the figures it comes from. `blockers` lists what prevents a\nproposal (draft entries and entries or documents waiting for approval dated in the year, a\nlast period that is not open, a missing annual-result account, a year that is already held);\n`can_propose` is true when there is none. Nothing is stored, so an agent may call it. Closing\nentries of the year (source `close`) are left out of the figures, so the preview of a closed\nyear is what it was before the close.",
        "operationId": "close_preview_v1_entities__entity__fiscal_years__year__close_preview_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, the calendar year it ends in, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "The fiscal year, the calendar year it ends in, e.g. `2026`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ClosePreview"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fiscal-years/{year}/close/cancel": {
      "post": {
        "tags": [
          "year-end close"
        ],
        "summary": "Cancel a proposed year-end close",
        "description": "Withdraw a proposal that is still `pending`: its approval request and its closing entry are\nrejected and the lock on the year is lifted. A human only (`close_fiscal_year`), with a\nreason, audited as `year_close.cancel`. A rejected approval does the same. 404 when no\nproposal is pending; 409 for a closed year, which is reopened instead.",
        "operationId": "cancel_close_v1_entities__entity__fiscal_years__year__close_cancel_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, the calendar year it ends in, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "The fiscal year, the calendar year it ends in, e.g. `2026`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/erp__features__close__contracts__year_close__ReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/YearCloseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/fiscal-years/{year}/opening-balances": {
      "get": {
        "tags": [
          "year-end close"
        ],
        "summary": "Get the opening balances of a fiscal year",
        "description": "The balance sheet at the day before the year starts: what the books continue with. Nothing\nis posted at the start of a year; after a year-end close the profit and loss accounts start at\nzero and the balance sheet accounts carry their balances, so this equals the closing balance\nsheet of the year before, account by account. 422 for a year that does not exist.",
        "operationId": "opening_balances_v1_entities__entity__fiscal_years__year__opening_balances_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, the calendar year it ends in, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "The fiscal year, the calendar year it ends in, e.g. `2026`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceSheet"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fiscal-years/{year}/reopen-close": {
      "post": {
        "tags": [
          "year-end close"
        ],
        "summary": "Reopen a closed fiscal year",
        "description": "The decision to reopen a closed year: it reopens the period that holds the closing entry and\n**reverses the closing entry itself** (same date, same period), then sets the close\n`reopened`; periods reopen as before and the year can be closed again. A human with the\n`approve` scope and the policy's `reopen_period` (agents are denied), a reason, audited as\n`year_close.reopen`. The reversal needs no second approval: this decision covers it. Refused\nwith 409, listing them, while a resolution on the result is still posted or waits for approval\n(reverse it first); 404 when the year has no closed year close. A period of a closed year\ncannot be reopened by `POST /v1/periods/{period_id}/reopen` while its close stands.",
        "operationId": "reopen_close_v1_entities__entity__fiscal_years__year__reopen_close_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, the calendar year it ends in, e.g. `2026`.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "The fiscal year, the calendar year it ends in, e.g. `2026`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/erp__features__close__contracts__year_close__ReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/YearCloseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/fx/convert": {
      "get": {
        "tags": [
          "exchange rates"
        ],
        "summary": "Convert an amount at the ECB rate",
        "description": "The amount in the other currency at the ECB rate of the fixing on or before the date,\nwith the rate, its inverse, the route and the fixing day used.\n\n`converted` is `amount` times the 10-decimal `rate`, rounded half-even to the minor unit of\nthe target currency, as data-vNext's `/v1/fx/convert` rounds. The result is **indicative**: the\nbooks round half-up, so a booked amount can differ by one minor unit on an exact tie. It uses\nthe ECB rate the books use, not the official VAT rate (`/tax-rates`). 422 for a currency the\nECB does not publish or an amount with more than 18 integer digits; 404 if there is no fixing\nwithin 7 days before the date.",
        "operationId": "convert_v1_entities__entity__fx_convert_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "amount",
            "in": "query",
            "required": true,
            "schema": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                }
              ],
              "description": "The amount in the `from` currency, a decimal such as `1250.50`.",
              "examples": [
                "1250.50"
              ],
              "title": "Amount"
            },
            "description": "The amount in the `from` currency, a decimal such as `1250.50`."
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 3,
              "description": "ISO 4217 code of the currency to convert from.",
              "examples": [
                "USD"
              ],
              "title": "From"
            },
            "description": "ISO 4217 code of the currency to convert from."
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 3,
              "description": "ISO 4217 code of the currency to convert to.",
              "examples": [
                "CHF"
              ],
              "title": "To"
            },
            "description": "ISO 4217 code of the currency to convert to."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is.",
              "examples": [
                "2026-09-26"
              ],
              "title": "Date"
            },
            "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FxConversion"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fx/exposure": {
      "get": {
        "tags": [
          "exchange rates"
        ],
        "summary": "Get the foreign-currency exposure",
        "description": "Open receivables, open payables and foreign-currency bank balances by currency, in the\ntransaction currency and in the functional currency at the date's rate, against the amount\nbooked: `difference` is how far each balance moves if revalued, and `unrealised` the result\n(gain positive) the period-end FX revaluation would post.\n\nIt uses the revaluation's own selection, so at a period end `totals.unrealised` is the\nrevaluation's balancing line: posted documents in another currency than the functional one,\nopen at the date (payments and credit notes posted on or before it), and the balances of\nforeign-currency asset accounts; each value rounded half up to the minor unit. Credit notes\ncount negative. Each figure's `count` is the number of rows `/exposure/items` lists for it.",
        "operationId": "exposure_v1_entities__entity__fx_exposure_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is.",
              "examples": [
                "2026-09-26"
              ],
              "title": "Date"
            },
            "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FxExposure"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fx/exposure/items": {
      "get": {
        "tags": [
          "exchange rates"
        ],
        "summary": "List the positions behind the exposure",
        "description": "The open documents and bank balances that make up `/exposure`, with the amount in the\ntransaction currency, the booked amount, the value at the date's rate and the difference.\n`total` is the number of matching positions and equals the `count` of the matching cells of\n`/exposure`; a credit note is negative. Ordered by currency, side and number or code.",
        "operationId": "exposure_items_v1_entities__entity__fx_exposure_items_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is.",
              "examples": [
                "2026-09-26"
              ],
              "title": "Date"
            },
            "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is."
          },
          {
            "name": "side",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "bank",
                    "payables",
                    "receivables"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`receivables`, `payables` or `bank`; default all three.",
              "title": "Side"
            },
            "description": "`receivables`, `payables` or `bank`; default all three."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "minLength": 3,
                  "maxLength": 3
                },
                {
                  "type": "null"
                }
              ],
              "description": "ISO 4217 code to filter on; default every foreign currency.",
              "examples": [
                "USD"
              ],
              "title": "Currency"
            },
            "description": "ISO 4217 code to filter on; default every foreign currency."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "Page size, 1 to 500 (default 100).",
              "default": 100,
              "title": "Limit"
            },
            "description": "Page size, 1 to 500 (default 100)."
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Positions to skip, for the next page.",
              "default": 0,
              "title": "Offset"
            },
            "description": "Positions to skip, for the next page."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FxExposureItems"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fx/history": {
      "get": {
        "tags": [
          "exchange rates"
        ],
        "summary": "Get the rate history of a currency pair",
        "description": "The daily ECB cross rate of a pair over a range, for a chart and a table: every fixing\nday's rate (weekends and holidays have none), the first and last rate, the minimum and\nmaximum with the day each occurred, the **average** and the change.\n\nThe average is the arithmetic mean of the daily cross rates, rounded to 10 decimals\nhalf-even: the method of the IAS 21 average, applied to the range. `month` adds the IAS 21\naverage and closing rate of the latest completed month in the range, from data-vNext's\n`/v1/fx/period-rates`: the closing rate is the one the period-end revaluation uses. 422 for\na currency the ECB does not publish, equal currencies, a reversed range or one over 1830\ndays; 404 if the range has no fixing of both currencies.",
        "operationId": "history_v1_entities__entity__fx_history_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "base",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 3,
              "description": "ISO 4217 code of the currency priced: `1 base = rate quote`.",
              "examples": [
                "USD"
              ],
              "title": "Base"
            },
            "description": "ISO 4217 code of the currency priced: `1 base = rate quote`."
          },
          {
            "name": "quote",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 3,
              "description": "ISO 4217 code of the currency the rate is in; must differ from `base`.",
              "examples": [
                "CHF"
              ],
              "title": "Quote"
            },
            "description": "ISO 4217 code of the currency the rate is in; must differ from `base`."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First day of the range (ISO 8601). Default: 30 days before `end`.",
              "examples": [
                "2026-08-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range (ISO 8601). Default: 30 days before `end`."
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last day of the range (ISO 8601). Default: today where the entity is. The range covers at most 1830 days.",
              "examples": [
                "2026-08-31"
              ],
              "title": "End"
            },
            "description": "Last day of the range (ISO 8601). Default: today where the entity is. The range covers at most 1830 days."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FxHistory"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fx/matrix": {
      "get": {
        "tags": [
          "exchange rates"
        ],
        "summary": "Get the cross-rate matrix of a set of currencies",
        "description": "The cross rate of every currency pair of a set. Read it as `1 row = x column`:\n`rows[i].rates[j]` is the units of `currencies[j]` one `currencies[i]` buys, and the diagonal\nis 1.\n\nEach cell is the ECB rate of the column currency divided by that of the row currency\n(triangulated through EUR, `method`), computed at full precision and rounded once to 10\ndecimals half-even; the inverse cell is computed the same way round, not as 1 over the rounded\nrate, so a pair and its inverse differ from `1` by at most the rounding of 10 decimals.\n422 for a currency the ECB does not publish or more than 24 currencies; 404 if there is no\nfixing within 7 days before the date.",
        "operationId": "matrix_v1_entities__entity__fx_matrix_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is.",
              "examples": [
                "2026-09-26"
              ],
              "title": "Date"
            },
            "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is."
          },
          {
            "name": "currencies",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Comma-separated ISO 4217 codes, e.g. `CHF,EUR,USD`, at most 24. Default: the entity's functional currency, the currencies it uses, and EUR, USD, CHF and GBP.",
              "examples": [
                "CHF,EUR,USD"
              ],
              "title": "Currencies"
            },
            "description": "Comma-separated ISO 4217 codes, e.g. `CHF,EUR,USD`, at most 24. Default: the entity's functional currency, the currencies it uses, and EUR, USD, CHF and GBP."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FxMatrix"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fx/rates": {
      "get": {
        "tags": [
          "exchange rates"
        ],
        "summary": "List exchange rates against the entity's currency",
        "description": "Every currency the ECB publishes against the entity's functional currency: the rate\n(`1 currency = rate functional`), its inverse, the fixing day used, and whether the entity\nuses the currency (documents, active bank accounts, open items; those first).\n\nRates are the ECB euro reference rates of the fixing, triangulated through EUR and rounded\nonce to 10 decimals half-even (`decimals`, `rounding`), so they equal data-vNext's\n`/v1/fx/convert`. `fixing_date` is the ECB day used, `fallback` is true when it is earlier\nthan `requested_date`, and `sources` names the authority. 404 if there is no fixing within\n7 days before the date; 422 if the functional currency is not an ECB currency.",
        "operationId": "rates_v1_entities__entity__fx_rates_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is.",
              "examples": [
                "2026-09-26"
              ],
              "title": "Date"
            },
            "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FxRates"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/fx/tax-rates": {
      "get": {
        "tags": [
          "exchange rates"
        ],
        "summary": "Compare accounting rates with the official VAT rates",
        "description": "For the entity's country, side by side: the **accounting rate** (the ECB rate the books\ntranslate documents, payments and revaluations at, for bookkeeping) and the **official VAT\nrate** (BAZG for Switzerland, MWSTV Art. 45; the monthly rates the BMF announces for Germany,\nderived from the ECB reference rates and read from the Bundesbank, UStG §16 Abs. 6; the rate\nfor the VAT amounts and turnover on the return), both\nas tax currency per one unit of the foreign currency, with the difference.\n\nThe VAT rate follows the method of the entity's VAT settings (`tax.method`). A rate that is\nnot published yet, or does not list the currency, is `provisional` with the reason. Where the\ncountry prescribes no official rate, or the entity does not book in its tax currency,\n`supported` is false and `rows` is empty. 404 if there is no ECB fixing within 7 days.",
        "operationId": "tax_rates_v1_entities__entity__fx_tax_rates_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is.",
              "examples": [
                "2026-09-26"
              ],
              "title": "Date"
            },
            "description": "The date the rates are for (ISO 8601, e.g. `2026-09-26`). The latest ECB fixing on or before it is used (up to 7 days back); a weekend or holiday therefore answers with the previous fixing and `fallback` true. Defaults to today where the entity is."
          },
          {
            "name": "currencies",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Comma-separated ISO 4217 codes, e.g. `CHF,EUR,USD`, at most 24. Default: the entity's functional currency, the currencies it uses, and EUR, USD, CHF and GBP.",
              "examples": [
                "CHF,EUR,USD"
              ],
              "title": "Currencies"
            },
            "description": "Comma-separated ISO 4217 codes, e.g. `CHF,EUR,USD`, at most 24. Default: the entity's functional currency, the currencies it uses, and EUR, USD, CHF and GBP."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FxTaxRates"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/grni": {
      "get": {
        "tags": [
          "goods received"
        ],
        "summary": "Goods received not invoiced on a day",
        "description": "The GR/IR open items: every purchase order line with goods or services received and not\nbilled on the day, at receipt value, and their total tied to the GR/IR account of the ledger\n(the difference is zero). The period-end accrual list.",
        "operationId": "grni_open_items_v1_entities__entity__grni_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01`.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01`."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day (end of day); default today.",
              "title": "As Of"
            },
            "description": "The day (end of day); default today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GrniReportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/imports": {
      "post": {
        "tags": [
          "imports"
        ],
        "summary": "Import customers, vendors, accounts, balances or open items",
        "description": "Bring a customer's existing books into the ledger from a CSV or Excel file.\n\nStart with a **dry run** (`mode=dry_run`, the default): it runs the same code as the\nimport in a savepoint, rolls it back, and returns every problem of the file at once, each\nwith its `line` (row of the file), `column` and `message`, plus a `summary` of what a commit\nwould create. Fix the file, repeat, then send it again with `mode=commit` and an\n`Idempotency-Key`. A commit is **all or nothing**: it applies every row in one\ntransaction, or, if any row has a problem, answers 422 with the same list of problems and\nchanges nothing. A retry with the same key and file returns the first answer.\n\nThe six types go through the same services as the API does, so every control applies:\n\n- `customers`, `vendors`: created like `POST /v1/entities/{entity}/parties`. A customer is\n  active; a person's new vendor is a **draft with an activation request**, and a second\n  person must approve it (`GET /v1/approvals`) before its bills can be posted or paid, unless\n  the organization's approval policy allows `activate_party` for vendors.\n- `accounts`: added like `POST /v1/entities/{entity}/accounts` (needs the admin scope and\n  the policy's `manage_accounts`).\n- `opening_balances`: the trial balance of the old books, **one balanced opening entry**\n  per entity dated `as_of` (source `opening`), posted through the approval policy. Rows for\n  the receivables and payables control accounts are not posted (their balances are the open\n  items); the difference is booked to the account with the role\n  `opening_balance_clearing`. A second opening entry is refused until the first is reversed:\n  to correct an opening entry, reverse it (`POST /v1/journal-entries/{id}/reverse`; a second\n  person approves the reversal), then import the balances again.\n- `open_receivables`, `open_payables`: every open invoice, bill or credit note becomes a\n  posted document with its original number, dates and open gross amount, booked against the\n  clearing account (receivables or payables control account against clearing), so nothing\n  is counted twice. The customer or vendor must exist and be active. Once the balances and\n  both lists agree, the clearing account is zero (`summary.clearing_balance`).\n\nAn `fx_rate` more than 10% away from the reference rate (ECB) of the opening date is a\nproblem of its row unless `confirm_rates` is true (see `confirm_rates`).\n\nAgent keys are refused (403). Refused: 404 for an unknown entity, 422 for an unreadable\nfile, a file over 5 MB or 2,000 rows, a missing `as_of`, and (on commit) any problem in the\nrows; 409 when the `Idempotency-Key` was used with another file. The commit is an audit\nevent (`import.commit`) with the file's SHA-256 next to the audit events of everything it\ncreated.",
        "operationId": "import_file_v1_entities__entity__imports_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_import_file_v1_entities__entity__imports_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataImportResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/imports/salesforce": {
      "post": {
        "tags": [
          "imports"
        ],
        "summary": "Import a Salesforce export",
        "description": "Bring a company's Salesforce data over, one object (one file) at a time: its users (linked\nto the people here by email), accounts (customers), products, price books and prices,\nopportunities (deals), and the tasks, events and notes about them.\n\nImport the files in the order of `object`: each links to those before it (a deal to its\naccount, a task to its deal, a price to its product and price book). Start with a **dry\nrun** (the default): it returns every problem with its `line` and the file's `column`, the\n`mapping` of our fields to the file's columns (by Salesforce API name or report label), and\na `summary` of what a commit would create. Name other columns in `mapping` where the file\ncalls a field differently (a custom field), then send the file with `mode=commit` and an\n`Idempotency-Key`. A commit is **all or nothing**.\n\n**Re-imports create nothing twice**: every record is kept with its Salesforce id, so the\nsame file or a newer export imports only what is new (`summary.already_imported` counts the\nrest). An account whose code or name is already a customer here is linked to it, not\ndoubled. Rows deleted in Salesforce (`IsDeleted`) are skipped.\n\nEvery record goes through the same controls as the API: customers under the approval\npolicy, VAT numbers checked (one that fails is kept and marked unverified), products on the\ndefault revenue account. Agent keys are refused (403). Refused: 404 for an unknown entity,\n422 for an unreadable file, a file over the limits, a bad `mapping`, and (on commit) any\nproblem in the rows; 409 when the `Idempotency-Key` was used with another file. The commit\nis an audit event (`import.salesforce`) with the file's SHA-256.",
        "operationId": "import_salesforce_v1_entities__entity__imports_salesforce_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_import_salesforce_v1_entities__entity__imports_salesforce_post"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesforceImportResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/imports/templates/{type}": {
      "get": {
        "tags": [
          "imports"
        ],
        "summary": "Download an import template",
        "description": "The columns of an import as a file you can fill in: `csv` or `xlsx`. The first row names\nthe columns (the [onboarding workflow](../workflows/onboard-a-customer.md) lists them);\namounts are plain decimals with a dot, dates `YYYY-MM-DD`, yes/no columns take `yes` or\n`no`. Every cell of the template is text a spreadsheet cannot run as a formula. The\nentity must be the caller's (404 otherwise).",
        "operationId": "download_template_v1_entities__entity__imports_templates__type__get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "type",
            "in": "path",
            "required": true,
            "schema": {
              "enum": [
                "accounts",
                "customers",
                "open_payables",
                "open_receivables",
                "opening_balances",
                "vendors"
              ],
              "type": "string",
              "description": "The kind of import: `customers`, `vendors`, `accounts`, `opening_balances`, `open_receivables` or `open_payables`.",
              "examples": [
                "vendors"
              ],
              "title": "Type"
            },
            "description": "The kind of import: `customers`, `vendors`, `accounts`, `opening_balances`, `open_receivables` or `open_payables`."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "xlsx"
              ],
              "type": "string",
              "description": "`csv` (UTF-8 with a byte order mark, comma delimited) or `xlsx`.",
              "default": "csv",
              "title": "Format"
            },
            "description": "`csv` (UTF-8 with a byte order mark, comma delimited) or `xlsx`."
          },
          {
            "name": "examples",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Include two example rows (default); `false` gives the header row only. Delete the examples before importing: they are rows like any other.",
              "default": true,
              "title": "Examples"
            },
            "description": "Include two example rows (default); `false` gives the header row only. Delete the examples before importing: they are rows like any other."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The template file: a header row with the columns, and two example rows unless `examples=false`.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/invoice-content": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "What an invoice must show about the seller and the customer",
        "description": "The fields of the company profile (`seller`) and of a customer's record (`buyer`) that an\ninvoice of this entity must show by the law of its country, each with its legal basis and\nwhether every invoice needs it or only some. The same rules decide `missing_content` on a\ndocument and refuse to print or send one that lacks them.",
        "operationId": "get_invoice_content_v1_entities__entity__invoice_content_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvoiceContentOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/leases": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "List leases",
        "description": "Every lease of the company by code, with its position at `as_of`: the liability (in the\nlease currency) and the part of it due within 12 months, the right-of-use asset's carrying\namount (functional currency) and the lease months ended by then that no period's lease\nentries booked yet. A draft or exempt lease shows no position.",
        "operationId": "list_leases_v1_entities__entity__leases_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date of the position figures, ISO 8601. Default: today where the company is.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The date of the position figures, ISO 8601. Default: today where the company is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LeaseLine"
                  },
                  "title": "Response List Leases V1 Entities  Entity  Leases Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/open-credits": {
      "get": {
        "tags": [
          "payments"
        ],
        "summary": "List amounts on account and open credit notes",
        "description": "What can still be applied to open invoices or bills with `POST /v1/applications`: posted\npayments and receipts with an amount on account left, and posted credit notes with an open\namount, oldest first, with what is left of each (applications waiting for approval reserve\ntheirs). 404 for an unknown customer or vendor.",
        "operationId": "open_credits_v1_entities__entity__open_credits_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Code (or id) of one customer or vendor; default: all of them.",
              "title": "Party"
            },
            "description": "Code (or id) of one customer or vendor; default: all of them."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "customer",
                    "vendor"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`customer` or `vendor`; default: both.",
              "title": "Kind"
            },
            "description": "`customer` or `vendor`; default: both."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OpenCredit"
                  },
                  "title": "Response Open Credits V1 Entities  Entity  Open Credits Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/overview": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Entity Overview",
        "description": "Role Center cues and KPIs of one entity: pending approvals, draft entries, unmatched\nbank lines, overdue receivables and payables per currency, cash, revenue and net income\nfor the month up to `as_of`, and the eight most recently posted entries. Amounts are in\nthe entity's functional currency unless stated per currency.",
        "operationId": "entity_overview_v1_entities__entity__overview_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day the cues are computed for, ISO 8601; default: today.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The day the cues are computed for, ISO 8601; default: today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Overview"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/parties": {
      "get": {
        "tags": [
          "parties"
        ],
        "summary": "List customers and vendors",
        "description": "Customers and vendors of an entity, ordered by code, with their open balances\n(open and overdue amounts of posted documents per currency; credit notes count negative)\nand the requests waiting for a second person (`pending_actions`). All filters combine\nwith AND. Someone who sees only their own or their team's records gets the customers those\npeople own or have deals with (and every vendor).",
        "operationId": "list_parties_v1_entities__entity__parties_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "customer",
                    "vendor"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`customer` or `vendor`; default: both.",
              "title": "Kind"
            },
            "description": "`customer` or `vendor`; default: both."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the name, VAT number (any part), code (starts with) or town (starts with); case-insensitive.",
              "title": "Q"
            },
            "description": "Text in the name, VAT number (any part), code (starts with) or town (starts with); case-insensitive."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "blocked",
                    "draft",
                    "inactive"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`active`, `draft` (not yet activated by a second person), `blocked` or `inactive`; default: all.",
              "title": "Status"
            },
            "description": "`active`, `draft` (not yet activated by a second person), `blocked` or `inactive`; default: all."
          },
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^[A-Za-z]{2}$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "ISO 3166-1 alpha-2 country, e.g. `DE`.",
              "title": "Country"
            },
            "description": "ISO 3166-1 alpha-2 country, e.g. `DE`."
          },
          {
            "name": "vat_number",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Part of the VAT number or UID; spaces, dots and case are ignored, so `811569` finds `DE 811 569 869`.",
              "title": "Vat Number"
            },
            "description": "Part of the VAT number or UID; spaces, dots and case are ignored, so `811569` finds `DE 811 569 869`."
          },
          {
            "name": "parent",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the subsidiaries of this party (its id): those naming it parent.",
              "title": "Parent"
            },
            "description": "Only the subsidiaries of this party (its id): those naming it parent."
          },
          {
            "name": "owner_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the customers this person owns (`GET /v1/people`).",
              "title": "Owner User Id"
            },
            "description": "Only the customers this person owns (`GET /v1/people`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Day the overdue amounts are counted to (ISO 8601, e.g. `2026-09-30`); default today where the entity is.",
              "title": "As Of"
            },
            "description": "Day the overdue amounts are counted to (ISO 8601, e.g. `2026-09-30`); default today where the entity is."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "Most parties returned, 1 to 1000.",
              "default": 1000,
              "title": "Limit"
            },
            "description": "Most parties returned, 1 to 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PartyRow"
                  },
                  "title": "Response List Parties V1 Entities  Entity  Parties Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "parties"
        ],
        "summary": "Create a customer or vendor",
        "description": "Create a customer or vendor in an entity, identified by `kind` and `code`. Without a\n`code` it gets the company's next number (`C-00001`, `V-00001`, counted per company and kind\nwithout gaps); a code given is kept as written. A draft\nparty is neither booked nor paid until a second person activates it. By default a customer\nis `active`; a person's new vendor is a `draft` with an activation request, an agent's vendor\n(or any party with bank details an agent creates) a plain `draft` (see the activate\noperation). The IBAN is checked and stored without spaces. Refuses with 409 when a\ncode given exists for that kind, 422 for an invalid IBAN, Leitweg-ID or cash discount terms, a\ncurrency without exchange rates or an IBAN of your own company, 404 for an unknown entity\nor account, and 403 when the approval policy denies activation. The answer lists existing\ncustomers or vendors it may duplicate (same VAT number, an IBAN in common or the same\nname); the party is created anyway.",
        "operationId": "create_party_v1_entities__entity__parties_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartyInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartyCreated"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/parties/{party}": {
      "get": {
        "tags": [
          "parties"
        ],
        "summary": "Get a customer or vendor card",
        "description": "A customer or vendor by code or id: master data (structured address, language,\nIBAN and further bank accounts, contacts, electronic address, Leitweg-ID), who created\nand activated it, open balances per currency, pending requests with who asked and, for\nbank details, the current and proposed values, `payment_blockers`, the reasons no\npayment to it can be released now, and for a customer with a credit limit its `credit`:\nwhat it owes and has on order against the limit, and the credit still available. 404 when\nnot found; 409 when the code names both a customer and a vendor and `kind` is missing.",
        "operationId": "get_party_v1_entities__entity__parties__party__get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "customer",
                    "vendor"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409).",
              "title": "Kind"
            },
            "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Day the overdue amounts are counted to (ISO 8601, e.g. `2026-09-30`); default today where the entity is.",
              "title": "As Of"
            },
            "description": "Day the overdue amounts are counted to (ISO 8601, e.g. `2026-09-30`); default today where the entity is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartyCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "parties"
        ],
        "summary": "Change a customer or vendor",
        "description": "Change a customer or vendor, e.g. its address, contacts or Leitweg-ID. Omitted or\n`null` fields stay as they are; `\"\"` clears a text field; `contacts` and `bank_accounts`\nreplace the whole list.\n\nNew bank details (`iban`, `bank_accounts`) are not applied: they become a request\nthat a second person approves (`pending` on the card), and payments to the party are\nblocked meanwhile. Once a document of the party is posted or pending approval, a new\n`name`, `vat_number`, `country`, `subdivision`, `currency` or `credit_limit` is such a\nrequest too. Only humans change bank or key details (403 for agents); a second open request\nof the same kind answers 409. A credit limit is for customers only (422,\n`credit_limit_customers_only`). `status: active` does what the activate operation does.",
        "operationId": "update_party_v1_entities__entity__parties__party__patch",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`."
          },
          {
            "name": "kind",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "customer",
                "vendor"
              ],
              "type": "string",
              "description": "`customer` or `vendor`; required.",
              "title": "Kind"
            },
            "description": "`customer` or `vendor`; required."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartyUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartyCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/parties/{party}/activate": {
      "post": {
        "tags": [
          "parties"
        ],
        "summary": "Activate a draft customer or vendor",
        "description": "Activate a draft customer or vendor (four eyes).\n\nA person with the approve scope who did not create the party activates it at once;\nanyone else's call (every call, when the approval policy says so) becomes an approval\nrequest (``pending``) for a second person. Agents are refused. Safe to repeat: a second\ncall answers 409 (already active, or already requested).",
        "operationId": "activate_party_v1_entities__entity__parties__party__activate_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "customer",
                    "vendor"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409).",
              "title": "Kind"
            },
            "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartyCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/parties/{party}/merge": {
      "post": {
        "tags": [
          "parties"
        ],
        "summary": "Merge a duplicate customer",
        "description": "Merge this customer, entered twice, into `into`, a customer of the same company\n(ADR-0089). Only a customer without business records of its own is merged: no document,\npayment, order, subscription, price list, mandate, won deal or request waiting for approval\nnames it (409 `party_merge_has_records` lists what does). Its contacts, deals, activities and\nsubsidiaries move to the customer that stays, its own field values fill the ones that one has\nnone of, and it becomes inactive for good (`merged_into` on its card). Returns the card of the\ncustomer that stays. Vendors are not merged. A person's decision: 403 `merge_agent` for an\nagent. 422 `merge_same` for itself; 409 `party_merged` if either was merged already,\n`party_merge_loop` if the one that stays belongs to its group below it.",
        "operationId": "merge_party_v1_entities__entity__parties__party__merge_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CustomerMerge"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartyCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/parties/{party}/status": {
      "post": {
        "tags": [
          "parties"
        ],
        "summary": "Block a customer or vendor, set it inactive, or make it active again",
        "description": "Ask a second person to change the status (four eyes, as a change of key details): the\nanswer lists the request in `pending` (action `change_party_status`), decided with\n`POST /v1/approvals/{id}/approve` or `reject` by someone other than the requester.\n\n`blocked`: no new documents, orders or subscriptions for the party and nothing paid to it\n(payment proposals leave its bills out, payments and payment files refuse it); what it pays\nstill settles its open items. Payments to it are blocked already while the block waits.\n`inactive`: no longer used, nothing paid to it or received from it; only a party without open\nitems, documents or payments waiting for approval, open purchase orders or active\nsubscriptions and recurring invoices (409 `party_has_open_items`). `active` makes a blocked or\ninactive party usable again; a draft has no status change (409 `party_status_move`), it is\nactivated instead. People only (403 for agents and when the policy denies\n`change_party_details`); 409 for a move the rules do not allow or a request already waiting.",
        "operationId": "change_party_status_v1_entities__entity__parties__party__status_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "customer",
                    "vendor"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409).",
              "title": "Kind"
            },
            "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PartyStatusInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PartyCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/parties/{party}/vat-check": {
      "post": {
        "tags": [
          "parties"
        ],
        "summary": "Check a customer's or vendor's VAT number in its public register",
        "description": "Ask the public register of the party's VAT number (VIES, the Swiss UID register or\nHMRC) whether it is registered for VAT, as `POST /v1/vat-registers/check` does, and keep a\ndefinite answer (`valid` or `invalid`) on the card (`vat_check`) and in the audit trail.\n\nFor a UK number, when the entity has a UK VAT number of its own, HMRC also gives a\nconsultation number (`reference`): the proof that the number was checked that day. Advice\nonly: nothing is refused on the answer. `unavailable` (the register did not answer) and\n`not_configured` (this server has no access to the register yet, e.g. HMRC credentials not\nset up) keep the last answer. 422 `no_vat_number` when the party has none; 429 past 30\nregister checks a minute per organization.",
        "operationId": "check_party_vat_number_v1_entities__entity__parties__party__vat_check_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`.",
              "examples": [
                "C-DE"
              ],
              "title": "Party"
            },
            "description": "Customer or vendor code, e.g. `C-DE` or `V-BM`."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "customer",
                    "vendor"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409).",
              "title": "Kind"
            },
            "description": "`customer` or `vendor`; needed when one code names both a customer and a vendor (otherwise 409)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegisterCheck"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/payment-proposals": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Suggest vendor payments",
        "description": "Suggest vendor payments: open bills due by `due_until`, or whose cash discount\nwould expire by then, with the amount after the discount. Nothing is stored; confirm\nthe reviewed lines with `POST /v1/entities/{entity}/payment-runs`. Each line says why it is\nproposed (`overdue`, `due` or `cash_discount`) and carries warnings such as a missing IBAN\nor a draft vendor. `bank_balances` gives, per currency, the bank account the run would pay\nfrom and its book balance on the payment date. 422 when cash discounts are taken but the\nentity has no cash discount account.",
        "operationId": "propose_payments_v1_entities__entity__payment_proposals_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProposalCriteria"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentProposal"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/payment-runs": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Create the payments of a proposal",
        "description": "Create the payments of a reviewed proposal, all or none: one per vendor (a bill\nwith a structured reference on its own), each through the approval policy: a payment\nis `posted` or `pending_approval`, counted in the result. Refuses with 422 when a line is\nnot a bill of the entity, a bill is listed twice, or an amount or cash discount is not\nallowed, in which case no payment is created. A run that takes a bank account below zero in\nthe books on the payment date is made, with one `warnings` line per account and its\n`warning_reasons` by code. Approved payments are released with\n`POST /v1/payment-exports`.",
        "operationId": "run_payments_v1_entities__entity__payment_runs_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentRunInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentRunResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/payment-status-reports": {
      "post": {
        "tags": [
          "banking"
        ],
        "summary": "Import the bank's status report on a payment file",
        "description": "Import the bank's pain.002 Customer Payment Status Report on a pain.001 file the entity\nreleased (ADR-0062).\n\nEach payment the report rejects (the whole file, a batch of it or the payment itself, status\n`RJCT`) is reversed through its approval policy, with the bank's reason (`code`, `text`): the\nbills it paid are open again once the reversal is posted, and the payment's row says why\n(`bank_refusal`). A reversal still needs a second person under the four-eyes rules (one\nasked by an agent, or of a payment someone else recorded); the bank's report stands for the\nconfirmation that the bank did not pay it. Nothing is done twice: a payment already reversed,\nor whose reversal waits, is reported as such, so the same report can be imported again. A\npayment a bank statement line shows executed is left as it is (`executed`). Refused (422): a\nfile that is no pain.002 report, one on a payment file the entity did not make\n(`status_report_unknown_file`), or one naming a payment not in that file.",
        "operationId": "import_status_report_v1_entities__entity__payment_status_reports_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_import_status_report_v1_entities__entity__payment_status_reports_post"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StatusReportResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/periods": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "List Periods",
        "description": "The entity's posting periods ordered by fiscal year and number, with their status\n(`open` or `closed`). Use the `id` of a period in the close endpoints.",
        "operationId": "list_periods_v1_entities__entity__periods_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the periods of this fiscal year, e.g. 2026.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "Only the periods of this fiscal year, e.g. 2026."
          },
          {
            "name": "on",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the periods containing this date (ISO 8601, e.g. 2026-09-15); a regular period comes before an adjustment period on the same day.",
              "examples": [
                "2026-09-15"
              ],
              "title": "On"
            },
            "description": "Only the periods containing this date (ISO 8601, e.g. 2026-09-15); a regular period comes before an adjustment period on the same day."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PeriodOut"
                  },
                  "title": "Response List Periods V1 Entities  Entity  Periods Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/purchase-orders": {
      "get": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "List Purchase Orders",
        "description": "Purchase orders of an entity, newest first.",
        "operationId": "list_purchase_orders_v1_entities__entity__purchase_orders_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "enum": [
                      "cancelled",
                      "closed",
                      "draft",
                      "open",
                      "partially_invoiced",
                      "partially_received",
                      "pending_approval"
                    ],
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "One or more statuses (repeat the parameter).",
              "title": "Status"
            },
            "description": "One or more statuses (repeat the parameter)."
          },
          {
            "name": "vendor",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Vendor code or id.",
              "title": "Vendor"
            },
            "description": "Vendor code or id."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Order date from.",
              "title": "Start"
            },
            "description": "Order date from."
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Order date to.",
              "title": "End"
            },
            "description": "Order date to."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the number, buyer reference or vendor.",
              "title": "Q"
            },
            "description": "Text in the number, buyer reference or vendor."
          },
          {
            "name": "review",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only orders with a paid bill that receipts recorded since would block.",
              "default": false,
              "title": "Review"
            },
            "description": "Only orders with a paid bill that receipts recorded since would block."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many orders to return, newest first; at most 1000.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many orders to return, newest first; at most 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OrderOut"
                  },
                  "title": "Response List Purchase Orders V1 Entities  Entity  Purchase Orders Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Create Purchase Order",
        "description": "Create a draft purchase order for an active vendor (numbered at once). The payment\nterms and currency default to the vendor's. Nothing is posted to the ledger.",
        "operationId": "create_purchase_order_v1_entities__entity__purchase_orders_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/purchase-settings": {
      "get": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Get Purchase Settings",
        "description": "The entity's matching tolerances (default 2% and 5.00 per line, the stricter).",
        "operationId": "get_purchase_settings_v1_entities__entity__purchase_settings_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Set Purchase Settings",
        "description": "Set the matching tolerances: a variance is allowed up to `tolerance_percent` of a\nline's expected amount and at most `tolerance_amount` (audited).",
        "operationId": "set_purchase_settings_v1_entities__entity__purchase_settings_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SettingsInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/quotes": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "List Quotes",
        "description": "Quotes of an entity, newest first. A draft or sent quote past its valid-until day is\n`expired`.",
        "operationId": "list_quotes_v1_entities__entity__quotes_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "enum": [
                      "accepted",
                      "cancelled",
                      "declined",
                      "draft",
                      "expired",
                      "sent"
                    ],
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "One or more statuses.",
              "title": "Status"
            },
            "description": "One or more statuses."
          },
          {
            "name": "customer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Customer code or id.",
              "title": "Customer"
            },
            "description": "Customer code or id."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the number, reference or customer.",
              "title": "Q"
            },
            "description": "Text in the number, reference or customer."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many to return, newest first; at most 1000.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many to return, newest first; at most 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SalesDocumentOut"
                  },
                  "title": "Response List Quotes V1 Entities  Entity  Quotes Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Create Quote",
        "description": "Create a draft quote, numbered at once (`QT-2026-000001`). The currency and payment terms\ndefault to the customer's, `valid_until` to 30 days on. Each line is priced as an invoice of\nthat day would be: the product's defaults and the VAT determined for the customer. Nothing is\nposted.",
        "operationId": "create_quote_v1_entities__entity__quotes_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesDocumentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/receivable-allowance/settings": {
      "get": {
        "tags": [
          "close"
        ],
        "summary": "Get the general allowance percents",
        "description": "The company's general allowance: a percent for each aging bucket and whether it is taken\nwith VAT. `default` is true while the suggested ones apply (0 % not yet due, 5 % overdue;\nwith VAT for Swiss and Liechtenstein companies).",
        "operationId": "allowance_settings_v1_entities__entity__receivable_allowance_settings_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AllowanceSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "close"
        ],
        "summary": "Set the general allowance percents",
        "description": "Set the percent for each of the five aging buckets (each once; 422 `allowance_buckets`\notherwise) and whether it is taken with VAT. The next allowance run uses them; audited.",
        "operationId": "update_allowance_settings_v1_entities__entity__receivable_allowance_settings_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AllowanceSettingsInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AllowanceSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/reminder-settings": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "Get the fees and default interest of the reminder levels",
        "description": "What a reminder letter of each level charges: the fee per letter and the flat fee once per\ninvoice to a business customer (in the functional currency), and the yearly default-interest\nrate for business customers and for consumers (actual/365, from the due date). Until settings\nare saved (`configured` false) the country's defaults apply: Switzerland and Liechtenstein\n5 % a year and no fee; Germany the base rate plus 9 points (business) or 5 points (consumers),\nshown at today's base rate and charged at each day's (it changes on 1 January and 1 July), and\nEUR 40 once per invoice to a business customer; elsewhere nothing. A German rate saved at\nits default keeps following the base rate; a rate changed is fixed.",
        "operationId": "get_reminder_settings_v1_entities__entity__reminder_settings_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "dunning"
        ],
        "summary": "Save the fees and default interest of the reminder levels",
        "description": "Replace what each of the three levels charges (each level once; 422\n`reminder_settings_levels` otherwise). Letters already made keep what they charged; the\nchange is in the audit trail with the values before and after.",
        "operationId": "put_reminder_settings_v1_entities__entity__reminder_settings_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReminderSettingsInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/reminders": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "List the reminder letters",
        "description": "The letters made in the entity, oldest first, with the invoices each named, each\nhand-over and its `state` (`unsent`, `out_of_date`, `handed_over`, `withdrawn`).",
        "operationId": "list_reminders_v1_entities__entity__reminders_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's (code or id).",
              "title": "Party"
            },
            "description": "Only this customer's (code or id)."
          },
          {
            "name": "document",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the letters naming this invoice (its id).",
              "title": "Document"
            },
            "description": "Only the letters naming this invoice (its id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ReminderOut"
                  },
                  "title": "Response List Reminders V1 Entities  Entity  Reminders Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reminders/proposal": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "List the customers due a reminder letter",
        "description": "Which customers are due a reminder letter today (in the entity's country; `as_of` says\nwhich day that is), one row per customer and currency, with the invoices it would name and\nits level: 1 payment reminder, 2 second reminder, 3 final reminder (`levels` says when each\nis due: a Swiss entity reminds 10 days after the due date, then 20 days after the reminder\nwas handed over, then 10; a German one 7, 14 and 10). An invoice is due its next level when\nit is open today and long enough past its due date, or since the last letter that named it\nwas handed over. There is no other day: the clock runs on real time and the amounts are\ntoday's. `unsent` lists the letters made and not handed over yet: they start no clock, so\nthe next level waits for them. `out_of_date` lists those that can no longer be sent (an\namount on them changed, or they are more than 7 days old): withdraw them.\n\nRead-only; no fee and no interest is claimed. A customer that is another entity of the\norganization is not reminded.",
        "operationId": "get_reminder_proposal_v1_entities__entity__reminders_proposal_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderProposal"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/aging": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Aging of receivables or payables",
        "description": "Open posted documents of one side with their open amount, days overdue and aging\nbucket (`current`, `1-30`, `31-60`, `61-90`, `90+` days past due), oldest due date\nfirst, and the totals per currency and bucket. Credit notes count negative; settled\ndocuments are left out. Amounts are in the document's currency; `open_functional` and\n`totals_functional` give the same in the entity's functional currency: the carrying amount the\nledger holds (the booked total less what the posted payments and credit notes relieved; a\npayment waiting for approval reserves the open amount but relieves nothing yet), the figures of\nthe analytics aging trend for that day. A document that pending payments reserve in full is\nlisted too (`reserved`, `open` zero), so those totals are complete. `reconciliation` sets them\nagainst the ledger's control account as of `as_of`: the balance, the revaluation postings that\nsit on it, and what is unexplained (zero when the books are in order).",
        "operationId": "aging_v1_entities__entity__reports_aging_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "side",
            "in": "query",
            "required": true,
            "schema": {
              "enum": [
                "payables",
                "receivables"
              ],
              "type": "string",
              "description": "`receivables`: sales invoices and credit notes; `payables`: purchase bills and vendor credit notes.",
              "title": "Side"
            },
            "description": "`receivables`: sales invoices and credit notes; `payables`: purchase bills and vendor credit notes."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Day the report is as of (ISO 8601, e.g. `2026-09-30`): overdue days are counted to it, only documents dated on or before it are listed, and a payment or credit note dated after it has not settled anything yet.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "Day the report is as of (ISO 8601, e.g. `2026-09-30`): overdue days are counted to it, only documents dated on or before it are listed, and a payment or credit note dated after it has not settled anything yet."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Aging"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/balance-sheet": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Balance Sheet",
        "description": "Assets, liabilities and equity as of a date, grouped by report line, in the entity's\nfunctional currency. Profit not yet closed to retained earnings is added to equity and\nshown separately as `unclosed_earnings`, so assets equal liabilities plus equity\n(`balanced`). `compare` or `compare_as_of` adds a comparative date.",
        "operationId": "balance_sheet_v1_entities__entity__reports_balance_sheet_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The report date, ISO 8601: everything posted on or before it.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The report date, ISO 8601: everything posted on or before it."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Show the report in another currency than the entity's own, e.g. `EUR`: income and expenses at each month's average ECB rate, assets and liabilities at the rate of the report date, equity at the rates of the days it was booked, the translation difference as its own equity line (IAS 21.39 to 21.41). `translation` names every rate used. A rate that is not published yet answers 409 `fx_rate_missing`.",
              "examples": [
                "EUR"
              ],
              "title": "Currency"
            },
            "description": "Show the report in another currency than the entity's own, e.g. `EUR`: income and expenses at each month's average ECB rate, assets and liabilities at the rate of the report date, equity at the rates of the days it was booked, the translation difference as its own equity line (IAS 21.39 to 21.41). `translation` names every rate used. A rate that is not published yet answers 409 `fx_rate_missing`."
          },
          {
            "name": "compare",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "const": "prior_year_end",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`prior_year_end`: add the balance sheet on the last day of the previous fiscal year (the day before the fiscal year of `as_of` starts) and the change, per account, per section and in total (`comparative`). Works with `currency` too. There is no budget comparison: budgets plan revenue and expenses only.",
              "title": "Compare"
            },
            "description": "`prior_year_end`: add the balance sheet on the last day of the previous fiscal year (the day before the fiscal year of `as_of` starts) and the change, per account, per section and in total (`comparative`). Works with `currency` too. There is no budget comparison: budgets plan revenue and expenses only."
          },
          {
            "name": "compare_as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Compare with the balance sheet at this date instead (ISO 8601); it wins over `compare`.",
              "examples": [
                "2025-12-31"
              ],
              "title": "Compare As Of"
            },
            "description": "Compare with the balance sheet at this date instead (ISO 8601); it wins over `compare`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BalanceSheet"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/cash-flow": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Cash Flow",
        "description": "Cash flow statement by the indirect method, in the entity's functional currency: the\nprofit of the posted entries dated from `start` to `end`, the amounts in it that are not\ncash (depreciation, gains and losses on disposals, unrealised exchange differences on cash),\nthe change of each balance sheet account in operating, investing or financing activities,\nand the effect of exchange rate changes on cash. Cash is the accounts on the balance\nsheet's cash line: `opening_cash` plus `net_change` is `closing_cash` (`balanced`). Which\nline an account is on follows the rules of its chart (under the German chart, DRS 21:\ninterest received in investing, interest paid in financing). Year-end closing entries are\nleft out, and balances taken over from an earlier system count as the position at the\nstart. Fixed assets bought or sold on credit count in investing when paid (IAS 7.43), the\nunpaid part as a note; interest and income taxes paid are notes too (IAS 7.31-35). A bill\nbooked to a financing account (a lessor's bill on the lease liability) counts in financing\nwhen paid. A lease's commencement, change and early end and the FX revaluation of a loan or\nlease liability move no cash: they are on `op.noncash`, not in investing or financing; an\nASC 842 operating lease's cash flows are operating activities. Each line lists its\naccounts, to follow them into the general ledger. 422 `end_before_start` when `end` is\nbefore `start`.",
        "operationId": "cash_flow_v1_entities__entity__reports_cash_flow_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, ISO 8601.",
              "examples": [
                "2026-01-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, ISO 8601."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, ISO 8601, included.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, ISO 8601, included."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CashFlowStatement"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/dimension-balances": {
      "get": {
        "tags": [
          "dimensions",
          "reports"
        ],
        "summary": "Results by cost centre, profit centre or project",
        "description": "Revenue, expenses and result of the posted entries dated from `start` to `end`, per value\nof the dimension, with the accounts behind each, in the company's functional currency. Lines\nthat name no value are a row of their own, so the rows add up to the profit and loss report\nof the range; year-end closing entries are left out as there.",
        "operationId": "dimension_report_v1_entities__entity__reports_dimension_balances_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "dimension",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dimension's code, e.g. `cost_centre`.",
              "examples": [
                "cost_centre"
              ],
              "title": "Dimension"
            },
            "description": "The dimension's code, e.g. `cost_centre`."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, ISO 8601.",
              "examples": [
                "2026-09-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, ISO 8601."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, ISO 8601, included.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, ISO 8601, included."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/dimension-lines": {
      "get": {
        "tags": [
          "dimensions",
          "reports"
        ],
        "summary": "The postings of a cost centre, profit centre or project",
        "description": "The posted profit and loss lines behind a row of the results by dimension: those that name\nthe value (or none), of one account or every one, by date and posting order.",
        "operationId": "dimension_lines_v1_entities__entity__reports_dimension_lines_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "dimension",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The dimension's code, e.g. `cost_centre`.",
              "examples": [
                "cost_centre"
              ],
              "title": "Dimension"
            },
            "description": "The dimension's code, e.g. `cost_centre`."
          },
          {
            "name": "value",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The value's code, e.g. `CC-100`; omitted: the lines that name none.",
              "title": "Value"
            },
            "description": "The value's code, e.g. `CC-100`; omitted: the lines that name none."
          },
          {
            "name": "account",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this account, e.g. `6000`.",
              "title": "Account"
            },
            "description": "Only this account, e.g. `6000`."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, ISO 8601.",
              "examples": [
                "2026-09-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, ISO 8601."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, ISO 8601, included.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, ISO 8601, included."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DimensionLines"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/general-ledger": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "General Ledger",
        "description": "The posted lines of one account dated from `start` to `end`, by entry date and posting\norder, with the running balance in the account's normal direction (debit for assets and\nexpenses, credit for the others). `opening_balance` is everything posted before `start`.\nA line of a year-end closing entry has `closing` true. An unknown account answers 404.",
        "operationId": "general_ledger_v1_entities__entity__reports_general_ledger_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "account",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Account code (or id) in the entity, e.g. 6500.",
              "examples": [
                "6500"
              ],
              "title": "Account"
            },
            "description": "Account code (or id) in the entity, e.g. 6500."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, ISO 8601.",
              "examples": [
                "2026-09-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, ISO 8601."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, ISO 8601, included.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, ISO 8601, included."
          },
          {
            "name": "include_close",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Show the lines of year-end closing entries (marked `closing`); `false` leaves them out of the lines and the balances, so the account reads as it did before the close.",
              "default": true,
              "title": "Include Close"
            },
            "description": "Show the lines of year-end closing entries (marked `closing`); `false` leaves them out of the lines and the balances, so the account reads as it did before the close."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeneralLedger"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/period-profit-and-loss": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Period Profit And Loss",
        "description": "Income statement for a fiscal period and for the year to date through it, with the\nsame figures of the previous year as comparatives. `notes` says when there is no\ncomparative period or when it has a different number of days. Entries are selected by\nthe period they were posted in. Unknown year or period answers 404.",
        "operationId": "period_profit_and_loss_v1_entities__entity__reports_period_profit_and_loss_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, e.g. 2026.",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. 2026."
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "Period number within the year, from 1; adjustment periods follow the regular ones.",
              "examples": [
                9
              ],
              "title": "Period"
            },
            "description": "Period number within the year, from 1; adjustment periods follow the regular ones."
          },
          {
            "name": "comparatives",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` (default): add the same period of the previous fiscal year and its year to date; `false`: leave them out.",
              "default": true,
              "title": "Comparatives"
            },
            "description": "`true` (default): add the same period of the previous fiscal year and its year to date; `false`: leave them out."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Show the report in another currency than the entity's own, e.g. `EUR`: income and expenses at each month's average ECB rate, assets and liabilities at the rate of the report date, equity at the rates of the days it was booked, the translation difference as its own equity line (IAS 21.39 to 21.41). `translation` names every rate used. A rate that is not published yet answers 409 `fx_rate_missing`.",
              "examples": [
                "EUR"
              ],
              "title": "Currency"
            },
            "description": "Show the report in another currency than the entity's own, e.g. `EUR`: income and expenses at each month's average ECB rate, assets and liabilities at the rate of the report date, equity at the rates of the days it was booked, the translation difference as its own equity line (IAS 21.39 to 21.41). `translation` names every rate used. A rate that is not published yet answers 409 `fx_rate_missing`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PeriodProfitAndLoss"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/period-trial-balance": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Period Trial Balance",
        "description": "Trial balance after every posting through a fiscal period, on any calendar. On the\nlast day of the year the last regular period is before adjustments, an adjustment\nperiod after them. Entries are selected by the period they were posted in, not by date.\nUnknown year or period answers 404.",
        "operationId": "period_trial_balance_v1_entities__entity__reports_period_trial_balance_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "fiscal_year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "The fiscal year, e.g. 2026 (`GET /v1/entities/{entity}/fiscal-years`).",
              "examples": [
                2026
              ],
              "title": "Fiscal Year"
            },
            "description": "The fiscal year, e.g. 2026 (`GET /v1/entities/{entity}/fiscal-years`)."
          },
          {
            "name": "period",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "description": "Period number within the year, from 1; adjustment periods follow the regular ones (period 13 on a monthly calendar with one adjustment period).",
              "examples": [
                9
              ],
              "title": "Period"
            },
            "description": "Period number within the year, from 1; adjustment periods follow the regular ones (period 13 on a monthly calendar with one adjustment period)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PeriodTrialBalance"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/profit-and-loss": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Profit And Loss",
        "description": "Revenue, expenses and net income of the posted entries dated from `start` to `end`,\ngrouped into sections by report line, in the entity's functional currency. Unlike the\nperiod report it selects by entry date, not by fiscal period. `compare` and `budget` add\ncomparative figures; `notes` holds their caveats.",
        "operationId": "profit_and_loss_v1_entities__entity__reports_profit_and_loss_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the range, ISO 8601.",
              "examples": [
                "2026-09-01"
              ],
              "title": "Start"
            },
            "description": "First day of the range, ISO 8601."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the range, ISO 8601, included.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the range, ISO 8601, included."
          },
          {
            "name": "currency",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Show the report in another currency than the entity's own, e.g. `EUR`: income and expenses at each month's average ECB rate, assets and liabilities at the rate of the report date, equity at the rates of the days it was booked, the translation difference as its own equity line (IAS 21.39 to 21.41). `translation` names every rate used. A rate that is not published yet answers 409 `fx_rate_missing`.",
              "examples": [
                "EUR"
              ],
              "title": "Currency"
            },
            "description": "Show the report in another currency than the entity's own, e.g. `EUR`: income and expenses at each month's average ECB rate, assets and liabilities at the rate of the report date, equity at the rates of the days it was booked, the translation difference as its own equity line (IAS 21.39 to 21.41). `translation` names every rate used. A rate that is not published yet answers 409 `fx_rate_missing`."
          },
          {
            "name": "compare",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "const": "prior_year",
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`prior_year`: add the same range one year earlier (a month end stays a month end, so 29 February compares with 28 February) and the change, per account, per section and in total (`comparative`). Works with `currency` too.",
              "title": "Compare"
            },
            "description": "`prior_year`: add the same range one year earlier (a month end stays a month end, so 29 February compares with 28 February) and the change, per account, per section and in total (`comparative`). Works with `currency` too."
          },
          {
            "name": "budget",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true`: add the approved budget and the variance, per account, per section and in total (`budget`): per fiscal year, the approved version of its budget (of several, the one approved last), for the fiscal periods wholly in the range. Without an approved budget `budget` is null and `notes` says why; with `currency` it is left out (a budget is planned in the functional currency).",
              "default": false,
              "title": "Budget"
            },
            "description": "`true`: add the approved budget and the variance, per account, per section and in total (`budget`): per fiscal year, the approved version of its budget (of several, the one approved last), for the fiscal periods wholly in the range. Without an approved budget `budget` is null and `notes` says why; with `currency` it is left out (a budget is planned in the functional currency)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProfitAndLoss"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/trial-balance": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "Trial Balance",
        "description": "The trial balance as of a date: for every account with postings, the debit and credit\ntotals of all posted entries dated on or before `as_of` and the balance, in the entity's\nfunctional currency. `balanced` is true when total debits equal total credits, which it\nis unless the books are corrupt. `closing=exclude` leaves out the closing entries of a\nyear-end close (the pre-closing view).",
        "operationId": "trial_balance_v1_entities__entity__reports_trial_balance_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The report date, ISO 8601: everything posted on or before it.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The report date, ISO 8601: everything posted on or before it."
          },
          {
            "name": "closing",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "exclude",
                "include"
              ],
              "type": "string",
              "description": "`include` (default): the year-end closing entries count, so after a close the profit and loss accounts are at zero and the result is in equity. `exclude`: the view before the close of the fiscal year of `as_of`, with that year's profit and loss on its accounts; earlier years stay closed.",
              "default": "include",
              "title": "Closing"
            },
            "description": "`include` (default): the year-end closing entries count, so after a close the profit and loss accounts are at zero and the result is in equity. `exclude`: the view before the close of the fiscal year of `as_of`, with that year's profit and loss on its accounts; earlier years stay closed."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TrialBalance"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/reports/vat": {
      "get": {
        "tags": [
          "reports"
        ],
        "summary": "VAT report from the ledger",
        "description": "VAT of the posted entries between `start` and `end`, grouped by direction,\njurisdiction, treatment and rate from the tax data stored on the journal lines, in the\nentity's functional currency. It is reconciled with the movements on the VAT accounts:\n`unexplained_difference` shows VAT booked by manual journals. Settlements of VAT\nreturns are left out. This is a working report; the filed figures are in `/v1/vat-returns`.",
        "operationId": "vat_report_v1_entities__entity__reports_vat_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "First day of the period, inclusive (ISO 8601).",
              "examples": [
                "2026-09-01"
              ],
              "title": "Start"
            },
            "description": "First day of the period, inclusive (ISO 8601)."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Last day of the period, inclusive (ISO 8601).",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Last day of the period, inclusive (ISO 8601)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/role-accounts": {
      "post": {
        "tags": [
          "setup"
        ],
        "summary": "Add Role Accounts",
        "description": "Add the accounts of required roles the entity lacks (e.g. the cash discount roles of\nentities created before they existed) from its chart template. Refused, naming the\ncodes, when a template code is already in use; repeating it adds nothing. Answers 201\nwith the lists `added` and `present` (empty `added` when nothing was missing).",
        "operationId": "add_role_accounts_v1_entities__entity__role_accounts_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "chart",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Chart template id to take the accounts from (`GET /v1/charts`); default: the template the entity was created from.",
              "examples": [
                "ch_kmu"
              ],
              "title": "Chart"
            },
            "description": "Chart template id to take the accounts from (`GET /v1/charts`); default: the template the entity was created from."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleAccounts"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/rolling-forecast": {
      "get": {
        "tags": [
          "rolling-forecast"
        ],
        "summary": "Read the rolling forecast",
        "description": "The company's rolling forecast as its latest roll made it: each period's revenue, expenses\nand net income (closed periods as posted, open ones from the run rate, never below what is\nscheduled), and the totals of the periods not closed yet. The system makes the forecast and\nrolls it after each close; each roll is a draft a person approves (`/v1/plans`). 404\n`no_rolling_forecast` before the first scheduled run made it. Nothing is posted.",
        "operationId": "get_rolling_forecast_v1_entities__entity__rolling_forecast_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RollingForecastOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/sales-orders": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "List Sales Orders",
        "description": "Sales orders of an entity, newest first. An open order is `partially_invoiced` or\n`invoiced` by what its invoices that are not void or rejected add up to.",
        "operationId": "list_sales_orders_v1_entities__entity__sales_orders_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "array",
                  "items": {
                    "enum": [
                      "cancelled",
                      "closed",
                      "draft",
                      "invoiced",
                      "open",
                      "partially_invoiced"
                    ],
                    "type": "string"
                  }
                },
                {
                  "type": "null"
                }
              ],
              "description": "One or more statuses.",
              "title": "Status"
            },
            "description": "One or more statuses."
          },
          {
            "name": "customer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Customer code or id.",
              "title": "Customer"
            },
            "description": "Customer code or id."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the number, reference or customer.",
              "title": "Q"
            },
            "description": "Text in the number, reference or customer."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many to return, newest first; at most 1000.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many to return, newest first; at most 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SalesDocumentOut"
                  },
                  "title": "Response List Sales Orders V1 Entities  Entity  Sales Orders Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Create Sales Order",
        "description": "Enter a sales order directly as a draft (`SO-2026-000001`), for an order that came without\na quote; confirm it to invoice it. An accepted quote makes its order itself. Nothing is\nposted.",
        "operationId": "create_sales_order_v1_entities__entity__sales_orders_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesDocumentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/sales-tax": {
      "get": {
        "tags": [
          "sales tax"
        ],
        "summary": "Get the sales tax setup",
        "description": "A US company's states it is registered in (with each state's liability account and what\nit owes now), its jurisdictions and their rates (the one in force on `on`), its tax areas\nwith their combined rates, and the product taxability it recorded per state. `applies` is\nfalse for a company outside the US, which charges VAT.",
        "operationId": "get_setup_v1_entities__entity__sales_tax_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "on",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day the rates in force are shown for; default today.",
              "title": "On"
            },
            "description": "The day the rates in force are shown for; default today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxSetupOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/sales-tax/areas": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Add a tax area",
        "description": "A place's local jurisdictions (county, city, districts) on top of its state; a customer\nlocated there gets the area. Answers 422 for a jurisdiction of another state.",
        "operationId": "add_area_v1_entities__entity__sales_tax_areas_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxAreaInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxAreaOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/sales-tax/areas/{area}": {
      "patch": {
        "tags": [
          "sales tax"
        ],
        "summary": "Change a tax area",
        "description": "Renames the area or replaces its local jurisdictions; documents dated from now on use it.",
        "operationId": "update_area_v1_entities__entity__sales_tax_areas__area__patch",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "area",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "A tax area's code, e.g. `LOS-ANGELES`.",
              "title": "Area"
            },
            "description": "A tax area's code, e.g. `LOS-ANGELES`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxAreaUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxAreaOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/sales-tax/category-rules": {
      "put": {
        "tags": [
          "sales tax"
        ],
        "summary": "Set how much of a product category a state taxes",
        "description": "`taxable_percent` of the price of products of `category` is taxed in `state`: `0`\nexempt, `100` (also when nothing is recorded) fully taxed.",
        "operationId": "set_rule_v1_entities__entity__sales_tax_category_rules_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxCategoryRuleInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxCategoryRuleOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/sales-tax/jurisdictions": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Add a county, city or district",
        "description": "A local jurisdiction of a state with its first rate; a tax area names it to charge it.\nAnswers 409 when the code is taken.",
        "operationId": "add_jurisdiction_v1_entities__entity__sales_tax_jurisdictions_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxJurisdictionInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxJurisdictionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/sales-tax/jurisdictions/{jurisdiction}/rates": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Set a jurisdiction's rate from a day",
        "description": "A new rate from `valid_from` for documents dated on or after it (a rate of the same day\nis replaced); posted documents keep the rates they were charged at.",
        "operationId": "set_rate_v1_entities__entity__sales_tax_jurisdictions__jurisdiction__rates_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "jurisdiction",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "A jurisdiction's code, e.g. `CA-LA-DIST`.",
              "title": "Jurisdiction"
            },
            "description": "A jurisdiction's code, e.g. `CA-LA-DIST`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxRateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxJurisdictionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/sales-tax/periods": {
      "get": {
        "tags": [
          "sales tax"
        ],
        "summary": "List the sales tax return periods of a year",
        "description": "Each registration's periods of the year that have started, with the tax from the ledger\nand their state (`open`, `to_file`, `due_soon`, `overdue`, `awaiting_approval`, `filed`,\n`paid`) with the day each return is due, and the year's sales into states the\ncompany is not registered in.",
        "operationId": "list_periods_v1_entities__entity__sales_tax_periods_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "maximum": 2100,
              "minimum": 2000,
              "description": "The calendar year.",
              "title": "Year"
            },
            "description": "The calendar year."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxPeriodsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/sales-tax/registrations": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Register the company in a state",
        "description": "Records that the company is registered for sales tax in a state from a day (nexus): from\nthen on its sales to customers in that state are taxed. Creates the state's liability account\n(`2200-CA`, under the company's sales tax payable) and the state's jurisdiction at the state\nrate (`state_rate`, else the base rate data-vNext has). Answers 409 when already registered,\n422 for a company outside the US (`sales_tax_not_us`) or a state data-vNext has no rate for\nand none was given (`sales_tax_state_rate_unknown`). Needs the policy action\n`manage_accounts`.",
        "operationId": "register_v1_entities__entity__sales_tax_registrations_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxRegistrationInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxRegistrationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/sales-tax/registrations/{state}": {
      "patch": {
        "tags": [
          "sales tax"
        ],
        "summary": "Change a state registration",
        "description": "Changes the permit number, the last day (`registered_until`: no tax is charged in the\nstate after it) or the filing frequency. Only the fields sent change.",
        "operationId": "update_registration_v1_entities__entity__sales_tax_registrations__state__patch",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "state",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^US-[A-Z]{2}$",
              "description": "The state, e.g. `US-CA`.",
              "title": "State"
            },
            "description": "The state, e.g. `US-CA`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxRegistrationUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxRegistrationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/sales-tax/returns": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Record a sales tax return as filed",
        "description": "Records that the state's return for the period was filed with the state on `filed_on`,\nwith the state's confirmation number, and keeps the figures as they are now; a second person\napproves the record (`POST /v1/sales-tax-returns/{id}/approve`). Nothing is sent:\nthe application files no return, and in a test copy (`test_copy`) the record is local only.\nAnswers 409 when already recorded (withdraw it first), 422 for a day in the future or in the\nperiod. A person's act: needs the policy action `finalize_vat_return`, which agents are\nalways denied (403).",
        "operationId": "file_return_v1_entities__entity__sales_tax_returns_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxFileInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/sales-tax/returns/{state}/{period}": {
      "get": {
        "tags": [
          "sales tax"
        ],
        "summary": "Get a state's sales tax return",
        "description": "The state's return for the period from the posted journal lines: gross, exempt and taxable\nsales, the tax by jurisdiction, the check against the state's account, and the filing with\nits payments when recorded. Answers 422 for a period not of the state's filing frequency.",
        "operationId": "get_return_v1_entities__entity__sales_tax_returns__state___period__get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "state",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^US-[A-Z]{2}$",
              "description": "The state, e.g. `US-CA`.",
              "title": "State"
            },
            "description": "The state, e.g. `US-CA`."
          },
          {
            "name": "period",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}(-(0[1-9]|1[0-2]|Q[1-4]))?$",
              "description": "`2026-08`, `2026-Q3` or `2026`, by the state's filing frequency.",
              "title": "Period"
            },
            "description": "`2026-08`, `2026-Q3` or `2026`, by the state's filing frequency."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/sample-data": {
      "post": {
        "tags": [
          "test copies"
        ],
        "summary": "Add sample data to a test organization",
        "description": "Book a month of sample business into an entity of a **test organization** (a test copy or\na demo), to have something to look at and try things on: three sample customers and two\nsample vendors (created once, codes `SAMPLE-...`), four sales invoices and two bills dated\nin the current month up to today, the first customer's payment of the first invoice and the\npayment of the first bill. Everything goes through the ordinary services, with the entity's\nown VAT and accounts, booked as the system actor `sample`. Asking again adds another set.\n\nRefused with 409 in an organization that is not a test organization (sample data never goes\ninto real books) or when today's period is closed; 403 for an agent. Needs the `admin`\nscope and an `Idempotency-Key`. Recorded in the audit trail (`sample_data.add`).",
        "operationId": "add_sample_data_v1_entities__entity__sample_data_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code (or id) of the entity, e.g. `CH01`.",
              "title": "Entity"
            },
            "description": "Code (or id) of the entity, e.g. `CH01`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SampleDataOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/entities/{entity}/saved-reports": {
      "get": {
        "tags": [
          "saved reports"
        ],
        "summary": "List saved reports",
        "description": "The company's reports the caller may open: their own and those shared with them, the\npinned ones first.",
        "operationId": "list_saved_reports_v1_entities__entity__saved_reports_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "pinned",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only those on the caller's Home, in the order pinned.",
              "default": false,
              "title": "Pinned"
            },
            "description": "Only those on the caller's Home, in the order pinned."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SavedReportOut"
                  },
                  "title": "Response List Saved Reports V1 Entities  Entity  Saved Reports Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "saved reports"
        ],
        "summary": "Save a report",
        "description": "Keep a report: only `definition` is needed (the name defaults to the source's). Shared\nwith `everyone` or some `people`, they open it as themselves. A `schedule` e-mails it to its\nowner and people it is shared with. Audited as `saved_report.create`.",
        "operationId": "create_saved_report_v1_entities__entity__saved_reports_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SavedReportIn"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedReportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/saved-reports/run": {
      "post": {
        "tags": [
          "saved reports"
        ],
        "summary": "Run a report",
        "description": "Run a report without saving it: the rows (or groups, with their counts and sums) the\ncaller may see, the totals of everything found, and for each row where it opens in the app\n(each group carries the report of its rows, `drill`). Changes nothing. 422\n`saved_report_invalid` names a field its source does not have; `saved_report_day` a date\nthat is not one.",
        "operationId": "run_report_v1_entities__entity__saved_reports_run_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "de",
                "en",
                "fr",
                "it",
                "sv"
              ],
              "type": "string",
              "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`.",
              "default": "en",
              "title": "Language"
            },
            "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportDefinition"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/stock-valuation": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "Value the stock on a day",
        "description": "Each item's quantity and value at moving average on a day, the total, and the balance of\nthe inventory accounts in the ledger it ties to.",
        "operationId": "stock_valuation_v1_entities__entity__stock_valuation_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01`.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01`."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day (end of day); default today.",
              "title": "As Of"
            },
            "description": "The day (end of day); default today."
          },
          {
            "name": "warehouse",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this warehouse's quantities.",
              "title": "Warehouse"
            },
            "description": "Only this warehouse's quantities."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ValuationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/vat-periods": {
      "get": {
        "tags": [
          "vat returns"
        ],
        "summary": "List the return periods of a year",
        "description": "The year's return periods as set in the entity's VAT settings: the VAT return\nperiods and, when a recapitulative statement period is set, its periods too. Each row\nnames the live return of the period (`return_id`, `reference`, `payable`) and its\n`status`; a period without a draft, pending, final or amending return has the status\n`open`. Periods are calendar months, quarters, half years or years, independent of the\nfiscal calendar. Each row also says when its return is due to be filed and paid\n(`due_date`, by the country's rule, null where none is known) and, seen from today,\n`due_status`: `filed`, `upcoming`, `due_soon`, `overdue` or `unknown`.",
        "operationId": "vat_periods_v1_entities__entity__vat_periods_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "year",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "maximum": 2100,
              "minimum": 2000,
              "description": "Calendar year, 2000 to 2100.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "Calendar year, 2000 to 2100."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/VatPeriod"
                  },
                  "title": "Response Vat Periods V1 Entities  Entity  Vat Periods Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/vat-rate-types": {
      "get": {
        "tags": [
          "documents"
        ],
        "summary": "List the VAT rate types a document line can choose",
        "description": "The rate types the entity's VAT area has in force on the day (Germany has no\n`super_reduced`, France no `zero`), `standard` first, each with its rates and what they\napply to (`categories`), from data-vNext. A line sends the type as `rate_type`; where a\ntype has several rates or kinds of exemption (`category_needed`: France reduced 5.5 % for\nbooks and 10 % for restaurants, the Swiss exemptions), it also sends one of the rate's\ncategories as `tax_category`. A line of another type, or one that needs a category and\nnames none, is refused (`tax_rate_type_missing`, `tax_category_needed`).",
        "operationId": "vat_rate_types_v1_entities__entity__vat_rate_types_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "date",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day (ISO 8601) the rates are in force, usually the document date. Defaults to today where the entity is.",
              "examples": [
                "2026-09-22"
              ],
              "title": "Date"
            },
            "description": "The day (ISO 8601) the rates are in force, usually the document date. Defaults to today where the entity is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatRateTypes"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/vat-settings": {
      "get": {
        "tags": [
          "vat returns"
        ],
        "summary": "Get the VAT settings of an entity",
        "description": "How the entity files VAT: method, return period, recapitulative statement (ZM)\nperiod, tax number, net tax rates and settlement account. Until settings are saved\n(`configured` is false) the defaults apply: a Swiss entity files by the effective method\nper quarter, a German one with the standard method per month and a monthly ZM, a Spanish\none per quarter with a quarterly Modelo 349, any other entity per quarter.",
        "operationId": "get_settings_v1_entities__entity__vat_settings_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "vat returns"
        ],
        "summary": "Save the VAT settings of an entity",
        "description": "Saves how the entity files VAT (the body replaces the stored settings) and returns\nthem. The `effective` and `net_tax_rate` methods exist in Switzerland only and `standard`\neverywhere else; the net tax rate method needs the ESTV-approved rate series, each\nknown to the reference data, and at most one of them may leave its accounts empty.\nAnswers 422 for a method the country does not have, for net tax rates under another\nmethod, for an unknown account or rate series, or for a `tax_fx` method the country\ndoes not offer, for a period other than month or quarter in Italy or the United Kingdom,\nand 409 when `tax_fx` would change while posted documents converted with\nthe current method are not yet covered by a final return.",
        "operationId": "put_settings_v1_entities__entity__vat_settings_put",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatSettingsInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/entities/{entity}/vendors/{party}/statement": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "Get a vendor's statement: what we owe, by bill, credit note and payment",
        "description": "What we owe the vendor and how it came about: per currency, the opening balance on\n`start`, every bill, credit note and payment up to `end` with the running balance, and the\nclosing balance, in the currency of each movement (a vendor billing in euros has a block in\neuros). `open_items` are the bills and credit notes still open at the end of `end`, as in the\npayables aging; `closing_functional` is the vendor's balance on the payables control account\nin the functional currency.\n\nIt is read from the vendor's own lines on the payables control account, so the closing\nbalance is the one in the books; compare it with the closing balance of the statement the\nvendor sent. `their_reference` is the vendor's own number of each bill. Read-only: it posts\nnothing. 404 for an unknown entity or vendor (a customer is not a vendor), 422 when `start`\nis after `end`.",
        "operationId": "get_vendor_statement_v1_entities__entity__vendors__party__statement_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "party",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Vendor code, e.g. `V-BM`, or its id. A customer is not a vendor.",
              "examples": [
                "V-BM"
              ],
              "title": "Party"
            },
            "description": "Vendor code, e.g. `V-BM`, or its id. A customer is not a vendor."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The first day of the period, ISO 8601. What we owed before it is the opening balance.",
              "examples": [
                "2026-07-01"
              ],
              "title": "Start"
            },
            "description": "The first day of the period, ISO 8601. What we owed before it is the opening balance."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The last day of the period, ISO 8601, not before `start`.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "The last day of the period, ISO 8601, not before `start`."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "json",
                "pdf"
              ],
              "type": "string",
              "description": "`json` (default): the statement; `csv`: one row per movement with the opening and closing balance of each currency; `pdf`: an A4 PDF in the vendor's language (`language` chooses another), rendered now and not stored.",
              "default": "json",
              "title": "Format"
            },
            "description": "`json` (default): the statement; `csv`: one row per movement with the opening and closing balance of each currency; `pdf`: an A4 PDF in the vendor's language (`language` chooses another), rendered now and not stored."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "it",
                    "sv"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`format=pdf` only: `de`, `fr`, `it`, `en` or `sv`.",
              "title": "Language"
            },
            "description": "`format=pdf` only: `de`, `fr`, `it`, `en` or `sv`."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`csv` and `pdf`: `true` sends the file as an attachment.",
              "default": false,
              "title": "Download"
            },
            "description": "`csv` and `pdf`: `true` sends the file as an attachment."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "JSON (the statement), CSV (its movements) or the PDF in the vendor's language.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VendorStatement"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/withholding-tax": {
      "get": {
        "tags": [
          "withholding tax"
        ],
        "summary": "Get the withholding tax kept back from vendors in a period",
        "description": "Every posted bill and vendor credit note that kept withholding tax back: the vendor, the\nbill, the net amount the tax was taken on, the rate, the tax in the document currency and in\nthe functional currency as booked, and the code with whom it is paid to; totals per code and\ncurrency. A cash discount taken on such a bill reduced its base and its tax in proportion: by\nbill date it is a row of its own (`cash_discount`), by payment date the bill's base and tax\nare less it. By bill date the functional total is what the period's bills and discounts\nbooked on the withholding tax account (role `vendor_withholding_payable`); by payment date\neach payment's part is at the rate of its day. Paying the authority is a\npayment from the bank to that account (a bank line booked to it, or a journal entry): it is\nnot a control account. Read-only. 422 when `start` is after `end`.",
        "operationId": "get_report_v1_entities__entity__withholding_tax_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The first day of the period, ISO 8601.",
              "examples": [
                "2026-09-01"
              ],
              "title": "Start"
            },
            "description": "The first day of the period, ISO 8601."
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The last day of the period, not before `start`.",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "The last day of the period, not before `start`."
          },
          {
            "name": "basis",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "bill_date",
                "payment_date"
              ],
              "type": "string",
              "description": "`bill_date` (default): the tax of the bills and vendor credit notes dated in the period, and of the cash discounts taken in it, as booked; `payment_date`: the part of each bill's tax that payments made in the period released, at their rates, for authorities that are owed the tax when the vendor is paid.",
              "default": "bill_date",
              "title": "Basis"
            },
            "description": "`bill_date` (default): the tax of the bills and vendor credit notes dated in the period, and of the cash discounts taken in it, as booked; `payment_date`: the part of each bill's tax that payments made in the period released, at their rates, for authorities that are owed the tax when the vendor is paid."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "json"
              ],
              "type": "string",
              "description": "`json` (default) or `csv`: one row per document, its columns the fields of `rows` (their meanings are those of the fields).",
              "default": "json",
              "title": "Format"
            },
            "description": "`json` (default) or `csv`: one row per document, its columns the fields of `rows` (their meanings are those of the fields)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "JSON or CSV.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WithholdingReport"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/withholding-tax/codes": {
      "get": {
        "tags": [
          "withholding tax"
        ],
        "summary": "List the withholding tax codes for vendors",
        "description": "The withholding tax codes of the company's country a vendor can carry (`withholding_code`\non the vendor): Germany Paragraph 50a EStG, Italy ritenuta d'acconto, Spain IRPF, the US NRA\nand backup withholding, and others, each with its rate and whom it is paid to. A vendor may\nalso carry `custom` with a rate of its own. `account` is where bills book the tax.",
        "operationId": "list_codes_v1_entities__entity__withholding_tax_codes_get",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WithholdingCodes"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/entities/{entity}/year-close/catch-up": {
      "post": {
        "tags": [
          "year-end close"
        ],
        "summary": "Close the years booked before the books were closed",
        "description": "For an entity that has been posting for years: one entry (source `close`), dated the first\nday of `first_clean_year`, brings the cumulative balance of every profit and loss account of\neverything before that date to zero against `retained_earnings`. The most recent year may stay\nunappropriated (`leave_latest_year_unappropriated`): its result goes to `annual_result` and\nis appropriated later like a closed year's. A human (`close_fiscal_year`); by default a second\nperson approves; the same lock, digest and cancellation apply as to a year-end close. 409\n`catch_up_period_not_open` names the first period of the year when it is not open (open it\nor name a later year). Needs an `Idempotency-Key`.",
        "operationId": "catch_up_v1_entities__entity__year_close_catch_up_post",
        "parameters": [
          {
            "name": "entity",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CatchUpInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatchUpResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/expense-card-lines": {
      "get": {
        "tags": [
          "expenses"
        ],
        "summary": "List card payments",
        "description": "The payments the card issuers listed, newest first, with the expense each was matched\nto; `without_receipt` lists those still waiting for their receipt.",
        "operationId": "list_expense_card_lines_v1_expense_card_lines_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this company's (code or id)."
          },
          {
            "name": "card",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this card's.",
              "title": "Card"
            },
            "description": "Only this card's."
          },
          {
            "name": "without_receipt",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only those with no expense yet.",
              "default": false,
              "title": "Without Receipt"
            },
            "description": "Only those with no expense yet."
          },
          {
            "name": "mine",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only those of your own cards.",
              "default": false,
              "title": "Mine"
            },
            "description": "Only those of your own cards."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 5000,
              "minimum": 1,
              "description": "How many, newest first.",
              "default": 500,
              "title": "Limit"
            },
            "description": "How many, newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CardLineOut"
                  },
                  "title": "Response List Expense Card Lines V1 Expense Card Lines Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "expenses"
        ],
        "summary": "Add card payments",
        "description": "Payments as a card issuer lists them (a feed or an automation): each is matched by\nitself to its holder's receipt (the same amount within five days); one read before is\nskipped. An administrator's; needs an `Idempotency-Key`.",
        "operationId": "add_expense_card_lines_v1_expense_card_lines_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardLinesInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CardLinesResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/expense-cards": {
      "get": {
        "tags": [
          "expenses"
        ],
        "summary": "List cards",
        "description": "The company cards, by holder, with the vendor each is booked to and how many of its\npayments have no receipt yet.",
        "operationId": "list_expense_cards_v1_expense_cards_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this company's (code or id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CardOut"
                  },
                  "title": "Response List Expense Cards V1 Expense Cards Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "expenses"
        ],
        "summary": "Add a company card",
        "description": "A card a person pays with for the company (administrators): its holder and last four\ndigits. Its account with the issuer becomes a vendor of its own, activated through the\ncontrols; what is bought with the card is booked to it and kept out of payment runs. Needs\nan `Idempotency-Key`.",
        "operationId": "add_expense_card_v1_expense_cards_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CardOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/expense-cards/{card_id}": {
      "patch": {
        "tags": [
          "expenses"
        ],
        "summary": "Change a card",
        "description": "Stop using a card (`active` false) or use it again (administrators).",
        "operationId": "update_expense_card_v1_expense_cards__card_id__patch",
        "parameters": [
          {
            "name": "card_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the card (`GET /v1/expense-cards`).",
              "title": "Card Id"
            },
            "description": "Id of the card (`GET /v1/expense-cards`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CardUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CardOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/expense-cards/{card_id}/statement": {
      "post": {
        "tags": [
          "expenses"
        ],
        "summary": "Read a card statement",
        "description": "Add the payments of a card's statement file and match each to its receipt, as `POST\n/v1/expense-card-lines`. Needs an `Idempotency-Key`.",
        "operationId": "read_expense_card_statement_v1_expense_cards__card_id__statement_post",
        "parameters": [
          {
            "name": "card_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the card (`GET /v1/expense-cards`).",
              "title": "Card Id"
            },
            "description": "Id of the card (`GET /v1/expense-cards`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_read_expense_card_statement_v1_expense_cards__card_id__statement_post"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CardLinesResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/expenses": {
      "get": {
        "tags": [
          "expenses"
        ],
        "summary": "List expenses",
        "description": "The expenses, newest first, with what each is (receipt, category, VAT, project, card),\nwhat the AI reviewer found, the bill it is booked as and whether it is paid back.",
        "operationId": "list_expenses_v1_expenses_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this company's (code or id)."
          },
          {
            "name": "mine",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only the ones you paid.",
              "default": false,
              "title": "Mine"
            },
            "description": "Only the ones you paid."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "approved",
                    "draft",
                    "held",
                    "posted",
                    "rejected",
                    "withdrawn"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those in this status.",
              "title": "Status"
            },
            "description": "Only those in this status."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 2000,
              "minimum": 1,
              "description": "How many, newest first.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many, newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExpenseOut"
                  },
                  "title": "Response List Expenses V1 Expenses Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "expenses"
        ],
        "summary": "Claim an expense without a receipt",
        "description": "A company card payment whose receipt is lost (`card_line`: its day, amount and merchant\nare taken from it), or a ticket with no file: your draft, with the category and project\nfilled as for a receipt. Without a receipt the AI reviewer always holds it for a person.\nNeeds an `Idempotency-Key`.",
        "operationId": "create_expense_v1_expenses_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/expenses-reimbursement": {
      "get": {
        "tags": [
          "expenses"
        ],
        "summary": "Where you are paid back",
        "description": "The vendor you are paid back as and its IBAN; all null before your first expense or\naccount.",
        "operationId": "get_reimbursement_v1_expenses_reimbursement_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The company; default as above.",
              "title": "Entity"
            },
            "description": "The company; default as above."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReimbursementOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "expenses"
        ],
        "summary": "Set where you are paid back",
        "description": "Your own bank account for expenses you paid: kept on the vendor you are paid back as\n(made the first time, numbered as every vendor, and activated by the AI reviewer or a second\nperson). A new IBAN on an existing one is a change of bank details, which waits for a second\nperson as any vendor's; payments wait meanwhile.",
        "operationId": "set_reimbursement_v1_expenses_reimbursement_put",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReimbursementInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReimbursementOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/expenses/receipts": {
      "post": {
        "tags": [
          "expenses"
        ],
        "summary": "Claim an expense from a receipt's photo",
        "description": "Read a receipt and keep it as your draft expense, its fields filled by themselves: who was\npaid, when, the total and the VAT per rate from the receipt; the category (expense account)\nand project from what you booked before; your company card when the receipt or a card line\nsays so (`filled` tells how each was found). Check it and submit it with `POST\n/v1/expenses/{id}/submit`, or send `submit` true. 409 (`receipt_already_claimed`) when the\nfile is already an expense, 422 (`not_a_receipt`) for something else, 503 when no language\nmodel is configured. When no model answers in time the receipt is kept all the same, as your\ndraft with nothing read from it (`confidence` null), to fill in. Needs an `Idempotency-Key`.",
        "operationId": "claim_receipt_v1_expenses_receipts_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/Body_claim_receipt_v1_expenses_receipts_post"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/expenses/{expense_id}": {
      "get": {
        "tags": [
          "expenses"
        ],
        "summary": "Get an expense",
        "description": "The expense with its checks, its bill and whether it is paid back.",
        "operationId": "get_expense_v1_expenses__expense_id__get",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the expense (`GET /v1/expenses`).",
              "title": "Expense Id"
            },
            "description": "Id of the expense (`GET /v1/expenses`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "expenses"
        ],
        "summary": "Change your draft",
        "description": "Correct what was read or filled before you submit it; each field you change is marked\nas yours (`filled`). 403 (`expense_not_yours`) for another person's, 409\n(`expense_not_draft`) once submitted.",
        "operationId": "update_expense_v1_expenses__expense_id__patch",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the expense (`GET /v1/expenses`).",
              "title": "Expense Id"
            },
            "description": "Id of the expense (`GET /v1/expenses`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/expenses/{expense_id}/receipt": {
      "get": {
        "tags": [
          "expenses"
        ],
        "summary": "Download an expense's receipt",
        "description": "The photo or PDF of the receipt, byte for byte (SHA-256 in `X-Content-SHA256`); 404 for\nan expense without one.",
        "operationId": "expense_receipt_v1_expenses__expense_id__receipt_get",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the expense (`GET /v1/expenses`).",
              "title": "Expense Id"
            },
            "description": "Id of the expense (`GET /v1/expenses`)."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true`: as an attachment; default inline.",
              "default": false,
              "title": "Download"
            },
            "description": "`true`: as an attachment; default inline."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The receipt as it was sent.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "text/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/jpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "image/webp": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/expenses/{expense_id}/submit": {
      "post": {
        "tags": [
          "expenses"
        ],
        "summary": "Submit your expense",
        "description": "The AI reviewer checks it against the company's expense policy (receipt kept and\nreadable, not claimed twice, not too old, within the limit, a project where asked, VAT that\nadds up, the card line): every check passes and it is approved and booked at once as a bill\npaid back in the next payment run (`posted`); one warns and it waits in Approvals for a\nperson who may approve and did not pay it (`held`). In the `four_eyes` controls mode every\nexpense waits for such a person. 422 (`expense_incomplete`) without a total, day or\ncategory.",
        "operationId": "submit_expense_v1_expenses__expense_id__submit_post",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the expense (`GET /v1/expenses`).",
              "title": "Expense Id"
            },
            "description": "Id of the expense (`GET /v1/expenses`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/expenses/{expense_id}/withdraw": {
      "post": {
        "tags": [
          "expenses"
        ],
        "summary": "Withdraw your draft",
        "description": "Withdraw a draft you will not claim; it is kept (`withdrawn`), never deleted, and its\nreceipt may be claimed again.",
        "operationId": "withdraw_expense_v1_expenses__expense_id__withdraw_post",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the expense (`GET /v1/expenses`).",
              "title": "Expense Id"
            },
            "description": "Id of the expense (`GET /v1/expenses`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/exports": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "List the organization's exports",
        "description": "The organization's exports, newest first, with their status. Pages of `limit`: pass the\nlast `id` as `after` for the next one. Needs the `admin` and `audit` scopes.",
        "operationId": "list_exports_v1_exports_get",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Most exports returned, 1 to 100.",
              "default": 25,
              "title": "Limit"
            },
            "description": "Most exports returned, 1 to 100."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Continue after this export (its id, the last of the previous page); omit for the first page.",
              "title": "After"
            },
            "description": "Continue after this export (its id, the last of the previous page); omit for the first page."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExportOut"
                  },
                  "title": "Response List Exports V1 Exports Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "audit"
            ]
          },
          {
            "apiKeyAuth": [
              "audit"
            ]
          }
        ],
        "x-required-scope": "audit"
      },
      "post": {
        "tags": [
          "exports"
        ],
        "summary": "Export the organization's data",
        "description": "Ask for the complete package of the organization's data, for its own archive: every\ntable of every entity and year as CSV (UTF-8, documented schema) and JSON, the reports of\nevery entity and fiscal year as PDF and CSV, every stored file checked against its SHA-256,\nthe verification of every entity's hash chain, a manifest with the hash of every file\n(`manifest.sha256`, for `sha256sum -c`), the `index.xml` of the German Beschreibungsstandard\nwhere an entity is German, a program that verifies the package, and a README in the\nrequested language with the legal references. Nothing secret is in it (no API key hash, no\nsession token).\n\nThe export is built asynchronously from one consistent snapshot of the database, so it can\nbe large: the answer is `202` with the export in status `queued`; follow it with\n`GET /v1/exports/{id}` until it is `succeeded`, then download it\n(`GET /v1/exports/{id}/download`, or a link with `GET /v1/exports/{id}/link`). The package\nis kept for 30 days. One export at a time: `409 export_in_progress` while another is\nqueued or running. Allowed also while the organization is suspended (it changes none of the\nbooks). Needs the `admin` and `audit` scopes and a person's key, not an agent's. Starting is\nan audit event (`export.start`).\n\nA retry with the same `Idempotency-Key` returns the first answer and starts nothing more.",
        "operationId": "start_export_v1_exports_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "audit"
            ]
          },
          {
            "apiKeyAuth": [
              "audit"
            ]
          }
        ],
        "x-required-scope": "audit",
        "x-idempotency": "required"
      }
    },
    "/v1/exports/{run_id}": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "Get an export's status",
        "description": "One export: `queued`, `running` (with the stage it is in and its progress), `succeeded`\n(with the file's name, size and SHA-256, the hash of the package's own checksum list, the\nnumber of files and rows, whether it is complete, and the hand-over statement), `failed`\n(with the reason), or `expired` (the package was deleted after its 30 days). 404 for an\nunknown export or one of another organization. Needs the `admin` and `audit` scopes.",
        "operationId": "get_export_v1_exports__run_id__get",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of an export (`GET /v1/exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Run Id"
            },
            "description": "Id of an export (`GET /v1/exports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "audit"
            ]
          },
          {
            "apiKeyAuth": [
              "audit"
            ]
          }
        ],
        "x-required-scope": "audit"
      }
    },
    "/v1/exports/{run_id}/download": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "Download the package of an export",
        "description": "The package of a succeeded export, as a ZIP, streamed (it can be many gigabytes: use a\nclient that writes to a file, and compare the SHA-256 with `sha256` of the export or with\nthe `X-Content-SHA256` header). For a large package, `GET /v1/exports/{id}/link` gives a\nlink that downloads straight from the store. Every download is an audit event\n(`export.download`). 409 `export_not_ready` while the export has not succeeded or after it\nhas expired, 404 for an unknown export or one of another organization. Needs the `admin`\nand `audit` scopes.",
        "operationId": "download_export_v1_exports__run_id__download_get",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of an export (`GET /v1/exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Run Id"
            },
            "description": "Id of an export (`GET /v1/exports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The package: a ZIP, streamed (SHA-256 in `X-Content-SHA256`).",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "audit"
            ]
          },
          {
            "apiKeyAuth": [
              "audit"
            ]
          }
        ],
        "x-required-scope": "audit"
      }
    },
    "/v1/exports/{run_id}/link": {
      "get": {
        "tags": [
          "exports"
        ],
        "summary": "Get a link to download the package of an export",
        "description": "A signed link that downloads the package straight from the store, without credentials,\nfor seven days at most (and never beyond the package's own expiry). Anyone who holds the link\ncan download until it ends: treat it like a password. Giving the link is an audit event\n(`export.link`). 409 `export_not_ready` while the export has not succeeded or after it has\nexpired, and 409 `no_signed_link` on a deployment that cannot sign links (use `/download`).\nNeeds the `admin` and `audit` scopes.",
        "operationId": "export_link_v1_exports__run_id__link_get",
        "parameters": [
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of an export (`GET /v1/exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Run Id"
            },
            "description": "Id of an export (`GET /v1/exports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportLink"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "audit"
            ]
          },
          {
            "apiKeyAuth": [
              "audit"
            ]
          }
        ],
        "x-required-scope": "audit"
      }
    },
    "/v1/hotel-stays": {
      "get": {
        "tags": [
          "hospitality"
        ],
        "summary": "List stays",
        "description": "The stays by arrival and number, with their room type, customer, guests, nights, status\nand invoice.",
        "operationId": "list_hotel_stays_v1_hotel_stays_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "room_type",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this room type's (product code, with `entity`, or id).",
              "title": "Room Type"
            },
            "description": "Only this room type's (product code, with `entity`, or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "cancelled",
                    "checked_in",
                    "checked_out",
                    "reserved"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only `reserved`, `checked_in`, `checked_out` or `cancelled`.",
              "title": "Status"
            },
            "description": "Only `reserved`, `checked_in`, `checked_out` or `cancelled`."
          },
          {
            "name": "first_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those that leave on or after this day.",
              "title": "First Day"
            },
            "description": "Only those that leave on or after this day."
          },
          {
            "name": "last_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those that arrive on or before this day.",
              "title": "Last Day"
            },
            "description": "Only those that arrive on or before this day."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 5000,
              "minimum": 1,
              "description": "How many, by arrival and number.",
              "default": 500,
              "title": "Limit"
            },
            "description": "How many, by arrival and number."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StayOut"
                  },
                  "title": "Response List Hotel Stays V1 Hotel Stays Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "hospitality"
        ],
        "summary": "Reserve a stay",
        "description": "Reserve rooms of a type from arrival to departure for a customer: the rooms are booked\nfor each night (409 `capacity_full`, with the first night short, when too few are free) and\neach night's price is agreed now, in the customer's currency (422 `room_no_price` where a\nnight has none). Nothing is posted. Needs an `Idempotency-Key`.",
        "operationId": "reserve_stay_v1_hotel_stays_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StayInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StayOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/hotel-stays/{stay_id}": {
      "get": {
        "tags": [
          "hospitality"
        ],
        "summary": "Get a stay",
        "description": "The stay with its nights, status and invoice.",
        "operationId": "get_hotel_stay_v1_hotel_stays__stay_id__get",
        "parameters": [
          {
            "name": "stay_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stay.",
              "title": "Stay Id"
            },
            "description": "Id of the stay."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StayOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/hotel-stays/{stay_id}/cancel": {
      "post": {
        "tags": [
          "hospitality"
        ],
        "summary": "Cancel a stay",
        "description": "Cancel a reserved stay (a no-show too), which frees its rooms. 409 (`stay_status`)\nunless it is reserved.",
        "operationId": "cancel_stay_v1_hotel_stays__stay_id__cancel_post",
        "parameters": [
          {
            "name": "stay_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stay.",
              "title": "Stay Id"
            },
            "description": "Id of the stay."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StayOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/hotel-stays/{stay_id}/check-in": {
      "post": {
        "tags": [
          "hospitality"
        ],
        "summary": "Check guests in",
        "description": "Record the guests' arrival and the rooms given. 409 (`stay_not_arrived`) before the\narrival day, (`stay_status`) unless it is reserved.",
        "operationId": "check_in_stay_v1_hotel_stays__stay_id__check_in_post",
        "parameters": [
          {
            "name": "stay_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stay.",
              "title": "Stay Id"
            },
            "description": "Id of the stay."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckInInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StayOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/hotel-stays/{stay_id}/check-out": {
      "post": {
        "tags": [
          "hospitality"
        ],
        "summary": "Check guests out and draft the invoice",
        "description": "Record the day the guests left (default: the reserved departure, or today when they leave\nearly; a later day books the extra nights if free) and draft the stay's sales invoice: its\nnights at the agreed prices and the extras. 409 (`stay_status`) unless the guests are in.",
        "operationId": "check_out_stay_v1_hotel_stays__stay_id__check_out_post",
        "parameters": [
          {
            "name": "stay_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stay.",
              "title": "Stay Id"
            },
            "description": "Id of the stay."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckOutInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StayOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/hotel-stays/{stay_id}/invoice": {
      "post": {
        "tags": [
          "hospitality"
        ],
        "summary": "Draft a stay's invoice again",
        "description": "Draft the invoice of a checked-out stay whose invoice was rejected. 409 (`stay_invoiced`)\nwhile it has one, (`stay_status`) unless the guests are out.",
        "operationId": "invoice_stay_v1_hotel_stays__stay_id__invoice_post",
        "parameters": [
          {
            "name": "stay_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stay.",
              "title": "Stay Id"
            },
            "description": "Id of the stay."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StayOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/hubspot": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get HubSpot",
        "description": "Whether HubSpot can be connected here, whether HubSpot's consent page can be used, the\npermissions a private app needs, and each company connected: the account, the stage at which a\ncontact becomes a lead, the default owner, how far HubSpot was read and the last error.",
        "operationId": "get_hubspot_v1_hubspot_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubSpotSetup"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/hubspot/authorize": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Start connecting HubSpot on its consent page",
        "description": "HubSpot's consent page for the company: open `url`; HubSpot sends the browser back to\n`redirect_uri` with a `code` and a `state` for `POST /v1/hubspot/connections/oauth`, within 15\nminutes. 409 when this system has no HubSpot app (connect with a private app instead).",
        "operationId": "authorize_v1_hubspot_authorize_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HubSpotAuthorize"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubSpotAuthorizeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/hubspot/connections": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Connect HubSpot with a private app",
        "description": "Connect a company with the access token of a private app in its own HubSpot. HubSpot is\nasked for the account (proving the token) and Stabiso's properties are added to its contacts.\nFrom then on its contacts at the hand-over stage come in as leads every 5 minutes (the\nfirst round reads the last 90 days), and each contact is sent what became of its lead.\nConnecting again replaces the token. 409 in a test copy or when the company is connected to\nanother account; 422 when HubSpot refuses the token or a permission is missing.",
        "operationId": "connect_key_v1_hubspot_connections_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HubSpotKeyInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubSpotConnection"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/hubspot/connections/oauth": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Connect HubSpot with its consent page's answer",
        "description": "Finish connecting with the `code` and `state` HubSpot sent the browser back with (only\nfor whoever started it). 422 when the state is not theirs or too old; 409 as above.",
        "operationId": "connect_oauth_v1_hubspot_connections_oauth_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HubSpotOAuthInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubSpotConnection"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/hubspot/connections/{connection_id}": {
      "patch": {
        "tags": [
          "crm"
        ],
        "summary": "Change what HubSpot hands over",
        "description": "Change the hand-over stage or the default owner (from the next round on).",
        "operationId": "update_connection_v1_hubspot_connections__connection_id__patch",
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/hubspot`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Connection Id"
            },
            "description": "Id of the connection (`GET /v1/hubspot`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HubSpotUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubSpotConnection"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "crm"
        ],
        "summary": "Disconnect HubSpot",
        "description": "Disconnect: nothing more is read or sent, and a consent's token is taken back at HubSpot (a\nprivate app's token is deleted in HubSpot). The leads stay, and so does which contact each\ncame from, so connecting the same account again brings no contact in twice.",
        "operationId": "disconnect_v1_hubspot_connections__connection_id__delete",
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/hubspot`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Connection Id"
            },
            "description": "Id of the connection (`GET /v1/hubspot`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/hubspot/connections/{connection_id}/sync": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Read HubSpot now",
        "description": "A round now (they run every 5 minutes): read the contacts that changed, make leads of\nthe new ones and send each contact what became of its lead. 409 when HubSpot stopped\naccepting the connection (connect again) or in a test copy.",
        "operationId": "sync_connection_v1_hubspot_connections__connection_id__sync_post",
        "parameters": [
          {
            "name": "connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/hubspot`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Connection Id"
            },
            "description": "Id of the connection (`GET /v1/hubspot`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HubSpotSyncOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/ic/links": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "List the intercompany links",
        "description": "The evidence that a posted invoice or credit note of one entity has a counterpart in the\nother, newest first: both documents, the status, why a counterpart could not be made (`error`),\nwho posted the origin (that person does not accept the mirror), who accepted or rejected the\nmirror and why. A drafted mirror is accepted like any bill: a person in the receiving entity\nrecodes it if needed and submits it (`POST /v1/documents/{id}/submit`).",
        "operationId": "list_links_v1_ic_links_get",
        "parameters": [
          {
            "name": "relationship",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the links of this relationship (`GET /v1/ic/relationships`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Relationship"
            },
            "description": "Only the links of this relationship (`GET /v1/ic/relationships`)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "accepted",
                    "drafted",
                    "mirror_rejected",
                    "pending",
                    "rejected",
                    "waiting"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only links in this state: `drafted` are the mirror documents waiting to be accepted, `pending` those whose counterpart could not be made.",
              "examples": [
                "drafted"
              ],
              "title": "Status"
            },
            "description": "Only links in this state: `drafted` are the mirror documents waiting to be accepted, `pending` those whose counterpart could not be made."
          },
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only links where this entity is either side.",
              "examples": [
                "DE01"
              ],
              "title": "Entity"
            },
            "description": "Only links where this entity is either side."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "At most this many links, newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "At most this many links, newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LinkOut"
                  },
                  "title": "Response List Links V1 Ic Links Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/ic/links/{link_id}": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "Get an intercompany link",
        "description": "One link with its origin and counterpart documents. 404 when it does not exist or belongs\nto another organization.",
        "operationId": "get_link_v1_ic_links__link_id__get",
        "parameters": [
          {
            "name": "link_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the link (`GET /v1/ic/links`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Link Id"
            },
            "description": "Id of the link (`GET /v1/ic/links`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/ic/links/{link_id}/reject": {
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Reject the mirror of an intercompany document",
        "description": "The receiving entity refuses the draft: it is voided and the link becomes `rejected` with the\nreason, which the sender sees; the sender corrects with a credit note. A difference between the\ntwo sides that a rejected mirror leaves is **unexplained** in the reconciliation until then.\nHumans only, and not the person who posted the origin (`accept_own_ic_document`). 409 for a\nlink whose mirror is not a draft any more.",
        "operationId": "reject_link_v1_ic_links__link_id__reject_post",
        "parameters": [
          {
            "name": "link_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the link (`GET /v1/ic/links`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Link Id"
            },
            "description": "Id of the link (`GET /v1/ic/links`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RejectInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/ic/links/{link_id}/retry": {
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Make the counterpart of a link again",
        "description": "Repeat the construction of the counterpart for a link that is `pending` (its `error` says\nwhy: no VAT number, a vendor number already used in the receiving entity, a missing account) or\n`waiting` (a credit note whose invoice's mirror has been posted since). The origin stays posted\nwhatever happens here; the answer shows the new state. 409 for a link that is not pending or\nwaiting.",
        "operationId": "retry_link_v1_ic_links__link_id__retry_post",
        "parameters": [
          {
            "name": "link_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the link (`GET /v1/ic/links`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Link Id"
            },
            "description": "Id of the link (`GET /v1/ic/links`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LinkOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/ic/loans": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "List the intercompany loans",
        "description": "The loans of the organization, oldest first, each with its terms, who requested and\napproved it, the approval that waits, and what it stands at from its movements: the\n`principal` outstanding, the day interest is `accrued_through` and the `interest_open` (accrued\nand not settled). 404 for an entity that does not exist.",
        "operationId": "list_loans_v1_ic_loans_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the loans this entity lends or borrows.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only the loans this entity lends or borrows."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "closed",
                    "draft"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only loans in this state.",
              "examples": [
                "active"
              ],
              "title": "Status"
            },
            "description": "Only loans in this state."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "At most this many loans, oldest first.",
              "default": 200,
              "title": "Limit"
            },
            "description": "At most this many loans, oldest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LoanOut"
                  },
                  "title": "Response List Loans V1 Ic Loans Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Request an intercompany loan",
        "description": "Ask for a loan between the two entities of an **active relationship**. It is written\n`draft` and **a second person approves its terms** (`POST /v1/approvals/{approval_id}/approve`;\nthe policy action `approve_ic_agreement`, human only): the amount, the currency, the fixed\nrate with its arm's-length `interest_basis` in words (recorded, never judged), the day count,\nthe dates, the two bank accounts and whether the loan is part of the net investment (IAS\n21.15). The approval is bound to the terms by a digest and they never change afterwards. 409\n`role_missing` names an account the lender (`ic_loan_receivable`, `ic_other_receivable`,\n`ic_interest_income`) or the borrower (`ic_loan_payable`, `ic_other_payable`,\n`ic_interest_expense`) lacks, 409 without an active relationship or for a reference in use,\n422 for a bank account that is not an active asset account. Humans only. Needs an\n`Idempotency-Key`.",
        "operationId": "create_loan_v1_ic_loans_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LoanInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoanOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/ic/loans/{loan_id}": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "Get an intercompany loan",
        "description": "One loan with its terms and what it stands at. 404 when it does not exist or belongs to\nanother organization.",
        "operationId": "get_loan_v1_ic_loans__loan_id__get",
        "parameters": [
          {
            "name": "loan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the loan (`GET /v1/ic/loans`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Loan Id"
            },
            "description": "Id of the loan (`GET /v1/ic/loans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LoanOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/ic/loans/{loan_id}/drawdowns": {
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Draw down an intercompany loan",
        "description": "The lender pays out: `Dr ic_loan_receivable / Cr bank` in the lender, `Dr bank / Cr\nic_loan_payable` in the borrower, in the loan's currency at the ECB rate of the value date.\n409 for a loan that is not active, a value date outside the start and the maturity, or an\namount beyond what is left of the facility; 409 when the date is on or before the day interest\nis accrued through (accrue first, the day count would be wrong). Both entities' entries are\nmade in one transaction and each goes through its entity's posting policy (an entry that needs\napproval waits, and the reconciliation lists it as `loan_movement_missing` until it posts).\nA payout that takes the lender's bank account below zero in the books on the value date is\nmade, with a `warnings` line saying so and its `warning_reasons` by code (the money may be\nthere and not booked yet). Needs an `Idempotency-Key`.",
        "operationId": "drawdown_v1_ic_loans__loan_id__drawdowns_post",
        "parameters": [
          {
            "name": "loan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the loan (`GET /v1/ic/loans`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Loan Id"
            },
            "description": "Id of the loan (`GET /v1/ic/loans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MovementInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MovementOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/ic/loans/{loan_id}/interest": {
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Accrue the interest of an intercompany loan",
        "description": "Accrue the interest from the day after the last accrual (or from the start) through\n`through`, over the principal outstanding each day, by the loan's day count, rounded half to\neven once: the lender `Dr ic_other_receivable / Cr ic_interest_income`, the borrower `Dr\nic_interest_expense / Cr ic_other_payable`. `detail.segments` shows each stretch of days with\nits principal. 409 for a day on or before the last accrual, for a day in a period that has\nnot started yet (`period_not_started`), or when the interest is zero (no principal in the\nperiod). The close check `ic_interest` warns while a loan with principal\noutstanding is not accrued through the period's end. Both entities' entries are made in one\ntransaction and each goes through its entity's posting policy. Needs an\n`Idempotency-Key`.",
        "operationId": "accrue_v1_ic_loans__loan_id__interest_post",
        "parameters": [
          {
            "name": "loan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the loan (`GET /v1/ic/loans`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Loan Id"
            },
            "description": "Id of the loan (`GET /v1/ic/loans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InterestInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MovementOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/ic/loans/{loan_id}/repayments": {
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Repay an intercompany loan",
        "description": "The borrower pays back principal: each side's loan balance is relieved at its carrying\namount and the bank at the ECB rate of the day; the difference is the realised exchange result\n(`detail.realised`). The loan is `closed` when its principal and its open interest are both\nzero. 409 for more than the principal outstanding or a date on or before the last accrual.\nBoth entities' entries are made in one transaction and each goes through its entity's posting\npolicy. One that takes the borrower's bank account below zero in the books is made, with a\n`warnings` line. Needs an `Idempotency-Key`.",
        "operationId": "repayment_v1_ic_loans__loan_id__repayments_post",
        "parameters": [
          {
            "name": "loan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the loan (`GET /v1/ic/loans`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Loan Id"
            },
            "description": "Id of the loan (`GET /v1/ic/loans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MovementInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MovementOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/ic/movements": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "List the intercompany movements",
        "description": "The drawdowns, repayments, interest accruals, settlements and declared group dividends, by\nvalue date, each with both entities' entries and their state (a dividend's shareholder entry\nstays `draft` until a person of the shareholder accepts it). Append-only: a movement is never\nchanged or deleted.",
        "operationId": "list_movements_v1_ic_movements_get",
        "parameters": [
          {
            "name": "loan",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the movements of this loan.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Loan"
            },
            "description": "Only the movements of this loan."
          },
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only movements where this entity is either side.",
              "examples": [
                "DE01"
              ],
              "title": "Entity"
            },
            "description": "Only movements where this entity is either side."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "dividend_declared",
                    "interest_accrual",
                    "loan_drawdown",
                    "loan_repayment",
                    "settlement"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only movements of this kind.",
              "examples": [
                "interest_accrual"
              ],
              "title": "Kind"
            },
            "description": "Only movements of this kind."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Value date on or after this day.",
              "examples": [
                "2026-10-01"
              ],
              "title": "Start"
            },
            "description": "Value date on or after this day."
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Value date on or before this day.",
              "examples": [
                "2026-12-31"
              ],
              "title": "End"
            },
            "description": "Value date on or before this day."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "At most this many, by value date.",
              "default": 200,
              "title": "Limit"
            },
            "description": "At most this many, by value date."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/MovementOut"
                  },
                  "title": "Response List Movements V1 Ic Movements Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/ic/movements/{movement_id}": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "Get an intercompany movement",
        "description": "One movement with both entries. 404 when it does not exist or belongs to another\norganization.",
        "operationId": "get_movement_v1_ic_movements__movement_id__get",
        "parameters": [
          {
            "name": "movement_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the movement (`GET /v1/ic/movements`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Movement Id"
            },
            "description": "Id of the movement (`GET /v1/ic/movements`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MovementOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/ic/reconciliation": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "Reconcile the intercompany balances",
        "description": "For each relationship and each currency of its open items, what the two entities hold\ntowards each other **in the document currency** (so the FX revaluation cannot disturb it):\n`a_receivable`, `a_payable`, `b_receivable`, `b_payable`, the nets and `difference = a_net +\nb_net`, zero when both sides agree. The same figures per link and per group document\nnobody linked, each with a `reason`: timing reasons (`mirror_missing`, `mirror_draft`,\n`mirror_pending_approval`, `payment_in_transit`, `cutoff`) are explained and the counterpart's\nto resolve; `mirror_rejected`, `unlinked_document` and `amount_differs` are unexplained. The\ncarrying amounts in each functional currency and the difference converted to the tolerance\ncurrency at the ECB rate of the day are for information; the tolerance applies to that figure.\n`status` is the result the close check `ic_reconciled` takes: `pass`, `warn` (timing items\nonly) or `fail` (a part is unexplained). Open means what the books hold: the posted payments\nand credit notes up to the day.",
        "operationId": "reconciliation_v1_ic_reconciliation_get",
        "parameters": [
          {
            "name": "as_of",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "The day the open items are read as of, ISO 8601.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The day the open items are read as of, ISO 8601."
          },
          {
            "name": "relationship",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this relationship; default: every relationship that is not pending.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Relationship"
            },
            "description": "Only this relationship; default: every relationship that is not pending."
          },
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the relationships of this entity.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only the relationships of this entity."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reconciliation"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/ic/relationships": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "List the intercompany relationships",
        "description": "The relationships of the organization, oldest first, each with its terms, who requested\nand approved them, the approval that waits (`approval_id`), the four group parties, and the\ncounts the Intercompany page shows: `open_mirrors` (drafts waiting to be accepted),\n`not_made` (counterparts that could not be made) and `rejected_mirrors`; each is the number of\nlinks `GET /v1/ic/links` lists for that status. 404 for an entity that does not exist.",
        "operationId": "list_relationships_v1_ic_relationships_get",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "pending",
                    "suspended"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only relationships in this state.",
              "examples": [
                "active"
              ],
              "title": "Status"
            },
            "description": "Only relationships in this state."
          },
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the relationships of this entity (code or id), on either side.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only the relationships of this entity (code or id), on either side."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "At most this many relationships, oldest first.",
              "default": 200,
              "title": "Limit"
            },
            "description": "At most this many relationships, oldest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RelationshipOut"
                  },
                  "title": "Response List Relationships V1 Ic Relationships Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Request an intercompany relationship",
        "description": "Ask for intercompany trade between two entities of the organization. The relationship is\nwritten `pending` and **a second person approves its terms** (`POST\n/v1/approvals/{approval_id}/approve`; the approver is never the requester): the mirror mode, the\ntolerance of the reconciliation, the VAT group and the **transfer-pricing record** (method,\nmark-up, the basis in words, the date of the documentation), which the approvers see before\nthey decide; the ERP records it and never judges a price. The approval is bound to those terms\nby a digest: changing any of them later is a new request. On approval, in the same\ntransaction, the relationship becomes `active` and each entity gets a customer and a vendor that\n*is* the other entity (code `IC-<code>`), active at once, with name, address, VAT number and\nbank accounts read from the other entity's record. Refused with 409 `role_missing` while an\nentity has no account with the role `ic_ar_control` or `ic_ap_control` (the answer names the\nentity, the role and the code its chart template suggests), 409 when the pair already has a\nrelationship, and 422 for a VAT group across the border or without a start date and\nreference, a `cost_plus` without mark-up or an empty pricing basis. Humans only: the policy\naction `approve_ic_relationship` denies agents. Needs an `Idempotency-Key`.",
        "operationId": "create_relationship_v1_ic_relationships_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RelationshipInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RelationshipOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/ic/relationships/{relationship_id}": {
      "get": {
        "tags": [
          "intercompany"
        ],
        "summary": "Get an intercompany relationship",
        "description": "One relationship with its terms, the transfer-pricing record, the approval that waits and a\nchange of terms that waits (`pending_terms`), and its group parties. 404 when it does not\nexist or belongs to another organization.",
        "operationId": "get_relationship_v1_ic_relationships__relationship_id__get",
        "parameters": [
          {
            "name": "relationship_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the relationship (`GET /v1/ic/relationships`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Relationship Id"
            },
            "description": "Id of the relationship (`GET /v1/ic/relationships`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RelationshipOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "intercompany"
        ],
        "summary": "Change, suspend or resume an intercompany relationship",
        "description": "Send one kind of change. **`status: suspended`** (with a `reason`) stops new intercompany\npostings at once, one person; the open items stay and settle normally. **`status: active`** on\na suspended relationship, and **new terms** (mirror mode, tolerance, VAT group, pricing\nrecord), are approval requests: the terms in force stay until a second person approves, and the\nanswer's `approval_id` names the request (the approver sees the pricing record again). A\nrelationship that was never approved takes new terms at once and asks again; after a\nrejection any PATCH (even `{}`, the terms unchanged) asks again.\n**`refresh_parties`** alone reads the name, address, VAT number, country and bank accounts of\nthe two entities again into their four group parties (which are not edited by hand: a payment\nto a group entity goes only to a bank account registered for it). 409 while a request about\nthe relationship already waits, for a change that changes nothing and for a status the\nrelationship cannot move to; 422 for terms that are not coherent. Humans only.",
        "operationId": "update_relationship_v1_ic_relationships__relationship_id__patch",
        "parameters": [
          {
            "name": "relationship_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the relationship (`GET /v1/ic/relationships`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Relationship Id"
            },
            "description": "Id of the relationship (`GET /v1/ic/relationships`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RelationshipUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RelationshipOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/ic/settlements": {
      "post": {
        "tags": [
          "intercompany"
        ],
        "summary": "Settle intercompany interest or a group dividend",
        "description": "Pay accrued interest of a `loan`, or a declared group `dividend` (the id of its\n`dividend_declared` movement): the debtor `Dr ic_other_payable / Cr bank`, the creditor `Dr\nbank / Cr ic_other_receivable`, each balance relieved at its carrying amount and the bank at\nthe ECB rate of the day. The bank accounts default to the loan's (for a dividend, the\naccounts with the role `bank`). 409 for more than is open, or a dividend whose shareholder\nhas not accepted its entry yet. Both entities' entries are made in one transaction and each\ngoes through its entity's posting policy. One that takes the debtor's bank account below zero\nin the books is made, with a `warnings` line. Needs an `Idempotency-Key`.",
        "operationId": "settle_v1_ic_settlements_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SettlementInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MovementOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/industries": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "List the industries a company can choose",
        "description": "The industries a company may say it is in (its `industry`, set in `POST /v1/setup`, `POST\n/v1/entities` or `PATCH /v1/entities/{entity}`), each with how far it is built (`ready`,\n`partial`, `planned`), what the product does for it and the feature modules that serve it.\nThe industry puts its screens first in the app's menu and on its Home; it switches nothing\noff. Needs the `read` scope.",
        "operationId": "list_industries_v1_industries_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/IndustryOut"
                  },
                  "type": "array",
                  "title": "Response List Industries V1 Industries Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/invoices/{invoice}/qr-bill": {
      "get": {
        "tags": [
          "swiss payments"
        ],
        "summary": "Get the QR-bill of a sales invoice",
        "description": "Swiss QR-bill for the open amount of a posted sales invoice (id or number).\n\nWith a QR-IBAN the reference is a QR reference, otherwise an ISO 11649\ncreditor reference. ``format=svg|pdf`` returns the payment part with receipt\n(210 x 105 mm) per the Swiss Implementation Guidelines QR-bill 2.3. Refuses with\n422 when the document is not a sales invoice, is not in CHF or EUR or no CH/LI bank\naccount in its currency is registered (`PUT .../bank-accounts/{account}`), and with 409\nwhen the invoice is not posted or is already settled, and in a test copy (ADR-0039).",
        "operationId": "qr_bill_v1_invoices__invoice__qr_bill_get",
        "parameters": [
          {
            "name": "invoice",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Invoice"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "json",
                "pdf",
                "svg"
              ],
              "type": "string",
              "description": "`json` (default): the payload and bill data; `svg` or `pdf`: the payment part with receipt as an image or document.",
              "default": "json",
              "title": "Format"
            },
            "description": "`json` (default): the payload and bill data; `svg` or `pdf`: the payment part with receipt as an image or document."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "de",
                "en",
                "fr",
                "it",
                "sv"
              ],
              "type": "string",
              "description": "Language of the payment text (`en`, `de`, `fr`, `it` or `sv`): the message in the bill and the labels of the `svg` and `pdf` output (English labels for `sv`, which the Swiss standard has no words in).",
              "default": "en",
              "title": "Language"
            },
            "description": "Language of the payment text (`en`, `de`, `fr`, `it` or `sv`): the message in the bill and the labels of the `svg` and `pdf` output (English labels for `sv`, which the Swiss standard has no words in)."
          },
          {
            "name": "account",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "GL bank account code to be paid into, e.g. `1020`; default: a registered Swiss account in the invoice's currency, preferring one with a QR-IBAN.",
              "examples": [
                "1020"
              ],
              "title": "Account"
            },
            "description": "GL bank account code to be paid into, e.g. `1020`; default: a registered Swiss account in the invoice's currency, preferring one with a QR-IBAN."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "JSON (payload and data), SVG or PDF payment part with receipt.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QrBillOut"
                }
              },
              "image/svg+xml": {
                "schema": {
                  "type": "string"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/invoices/{invoice}/xrechnung": {
      "get": {
        "tags": [
          "e-invoicing"
        ],
        "summary": "Issue a sales invoice as XRechnung",
        "description": "XRechnung 3.0 (CII) for a posted sales invoice or credit note of a German entity.\n\nThe output is checked with the same EN 16931 and XRechnung rules as received\ninvoices; ``format=xml`` refuses (422) an invoice that breaks a fatal rule, for\nexample a customer without a Leitweg-ID or buyer reference (BR-DE-15) or an entity\nwithout a registered bank account (BR-DE-1). ``format=json`` shows the check. 422 also\nfor a document that is not a sales invoice or credit note or whose entity is not German;\n409 when it is not posted, and 409 `invoice_content_incomplete` when the entity's or the\ncustomer's record lacks content the law requires on an invoice (`missing` lists each field;\nsee `missing_content` on the document).\n\n**Archived as issued.** The first `format=xml` stores the file with its SHA-256 and links it\nto the document (`GET /v1/documents/{id}/files`, source `archived_output`); later requests\nreturn those bytes, as for the PDF (`GET /v1/documents/{id}/pdf`). The first output needs the\n`post` scope and an active organization (`409` `not_issued` otherwise); a test copy issues\nno e-invoice (409, ADR-0039).",
        "operationId": "xrechnung_v1_invoices__invoice__xrechnung_get",
        "parameters": [
          {
            "name": "invoice",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Document id (uuid) or number, e.g. `INV-2026-000001`.",
              "examples": [
                "INV-2026-000001"
              ],
              "title": "Invoice"
            },
            "description": "Document id (uuid) or number, e.g. `INV-2026-000001`."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "json",
                "xml"
              ],
              "type": "string",
              "description": "`xml` (default): the XRechnung file as an attachment; `json`: the check result (valid flag, violations and the invoice model).",
              "default": "xml",
              "title": "Format"
            },
            "description": "`xml` (default): the XRechnung file as an attachment; `json`: the check result (valid flag, violations and the invoice model)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "XRechnung 3.0 CII.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/XRechnungOut"
                }
              },
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/journal-entries": {
      "get": {
        "tags": [
          "journals"
        ],
        "summary": "List Entries",
        "description": "Journal entries of all statuses with their lines, newest first (by entry date, then by\ncreation time). All filters are optional and combine; `account` needs `entity`, else 422.",
        "operationId": "list_entries_v1_journal_entries_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries of this entity (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only entries of this entity (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries with this status: `draft`, `pending_approval`, `posted` or `rejected`.",
              "examples": [
                "posted"
              ],
              "title": "Status"
            },
            "description": "Only entries with this status: `draft`, `pending_approval`, `posted` or `rejected`."
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries created by this source: `manual` or the subledger or process that made them, e.g. `ar`, `ap`, `fa`, `bank`, `fx`, `close`.",
              "examples": [
                "manual"
              ],
              "title": "Source"
            },
            "description": "Only entries created by this source: `manual` or the subledger or process that made them, e.g. `ar`, `ap`, `fa`, `bank`, `fx`, `close`."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries dated on or after this day (ISO 8601).",
              "examples": [
                "2026-09-01"
              ],
              "title": "Start"
            },
            "description": "Only entries dated on or after this day (ISO 8601)."
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries dated on or before this day (ISO 8601).",
              "examples": [
                "2026-09-30"
              ],
              "title": "End"
            },
            "description": "Only entries dated on or before this day (ISO 8601)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Keep entries whose description or entry number contains this text (case-insensitive).",
              "examples": [
                "audit"
              ],
              "title": "Q"
            },
            "description": "Keep entries whose description or entry number contains this text (case-insensitive)."
          },
          {
            "name": "account",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries with a line on this account code (needs `entity`).",
              "examples": [
                "6500"
              ],
              "title": "Account"
            },
            "description": "Only entries with a line on this account code (needs `entity`)."
          },
          {
            "name": "min_amount",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number",
                  "minimum": 0.0
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only entries whose debits total at least this amount, in the entity's functional currency (decimal, e.g. 1000.00).",
              "examples": [
                "1000.00"
              ],
              "title": "Min Amount"
            },
            "description": "Only entries whose debits total at least this amount, in the entity's functional currency (decimal, e.g. 1000.00)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "description": "How many entries to return, newest first; at most 1000.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many entries to return, newest first; at most 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/JournalEntryOut"
                  },
                  "title": "Response List Entries V1 Journal Entries Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "journals"
        ],
        "summary": "Create a journal entry",
        "description": "Create a manual journal entry and, unless `submit` is false, submit it.\n\nThe entry must balance (debits equal credits; on a multi-currency entry an FX rounding\ndifference of up to 0.05 in functional currency is booked to the rounding account; a larger\none answers 422 `entry_off_in_currency` with the `limit`) and its date must fall in an open\nperiod. A rate typed on a line (`fx_rate`) more than 10% away from the reference rate (ECB)\nof the entry date answers 422 `fx_rate_implausible` naming both rates and the date, unless\n`confirm_rate` is true; without a reference rate for the currency or day it is not checked.\nControl accounts (bank, receivables, payables, fixed assets) cannot be used: they are\nposted through their subledgers.\n`source` and `provenance` are set by the server; sending others answers 422. The approval\npolicy decides (`result.policy`): `allow` posts it at once (`result.status` `posted`, with\nits `number`), `require_approval` leaves it `pending_approval` with an `approval_id`, and\n`deny` answers 403. An entry made by a key without the post scope always waits for\napproval. With `submit` false the status stays `draft` and `policy` shows what would\nhappen on submit.",
        "operationId": "create_journal_entry_v1_journal_entries_post",
        "parameters": [
          {
            "name": "submit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` (default): submit the entry through the approval policy at once. `false`: keep it as a draft; submit it later with `POST /v1/journal-entries/{entry_id}/submit`.",
              "default": true,
              "title": "Submit"
            },
            "description": "`true` (default): submit the entry through the approval policy at once. `false`: keep it as a draft; submit it later with `POST /v1/journal-entries/{entry_id}/submit`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntryInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/journal-entries/{entry_id}": {
      "get": {
        "tags": [
          "journals"
        ],
        "summary": "Get a journal entry",
        "description": "One journal entry with its lines, in any status. A posted entry carries its number and\nits place in the hash chain (`hash`, `prev_hash`).",
        "operationId": "get_entry_v1_journal_entries__entry_id__get",
        "parameters": [
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Journal entry id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Entry Id"
            },
            "description": "Journal entry id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalEntryOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "journals"
        ],
        "summary": "Change a draft entry",
        "description": "Replace the content of a draft entry: its date, description, lines, `auto_reverse_on`,\n`adjustment_period` (the body is the same as on create, and the whole entry is sent). It is\nchecked exactly as a new entry is (balance, open period, accounts, reversal date). The entry\nkeeps its id, `created_by` and `created_at`; the audit trail records the change\n(`journal.draft_updated`, before and after), and whoever changed it cannot approve its\nposting (four eyes).\n\nOnly a draft entered by hand (`source` `manual`) is changed: 409 `draft_not_editable` when\nthe entry waits for approval, is posted or rejected, and 409 `draft_from_process` for a\ndraft that a process made (FX revaluation, depreciation, revenue recognition and others),\nwhich is corrected by that process.",
        "operationId": "update_draft_v1_journal_entries__entry_id__put",
        "parameters": [
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Journal entry id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Entry Id"
            },
            "description": "Journal entry id."
          },
          {
            "name": "submit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`false` (default): keep the changed entry as a draft. `true`: submit it through the approval policy at once, as `POST /v1/journal-entries/{entry_id}/submit`.",
              "default": false,
              "title": "Submit"
            },
            "description": "`false` (default): keep the changed entry as a draft. `true`: submit it through the approval policy at once, as `POST /v1/journal-entries/{entry_id}/submit`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EntryInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      },
      "delete": {
        "tags": [
          "journals"
        ],
        "summary": "Delete a draft entry",
        "description": "Delete a draft entered by hand. A draft has no entry number yet, so no number is lost;\nthe audit trail keeps its date, description, amount and lines (`journal.draft_deleted`).\nThe same refusals as for a change: 409 `draft_not_editable` (not a draft; a posted entry is\nreversed instead) and 409 `draft_from_process` (made by a process).",
        "operationId": "delete_draft_v1_journal_entries__entry_id__delete",
        "parameters": [
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Journal entry id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Entry Id"
            },
            "description": "Journal entry id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/journal-entries/{entry_id}/reverse": {
      "post": {
        "tags": [
          "journals"
        ],
        "summary": "Reverse a posted entry",
        "description": "Reverse a posted manual entry or opening entry: the same lines with debit and credit\nswapped, dated `on` (default: the entry's own date). The `reason` is required (at most 500\ncharacters) and recorded on the reversal entry and in the audit trail. It goes through the\napproval policy (action `reverse_entry`): only a person reverses, never an agent (403).\n\nA person who created, posted or approved the entry reverses it at once and gets the reversal\nentry (200; `reverses_id` names the original, whose `reversed_by_id` is now set). If another\nperson created, posted or approved the entry, or the policy limits what one person posts, the\nreversal waits for a second person: answer 202 with the approval request, decided with\n`POST /v1/approvals/{approval_id}/approve` (four eyes; everything is checked again then). A\nrequest that nobody decides blocks the close of the entry's period (the close checklist counts\nit) until it is approved or rejected.\n\nOnly manual entries and opening entries are reversed here. The opening entry of a data import\nis the import's correction path (reverse it, then import the balances again) and always waits\nfor a second person (202); it leaves the open items and the clearing account in place, so the\nclose check `opening_clearing` fails until the balances are imported again. Entries of a\nsubledger or process (invoices, credit notes, bills, payments, depreciation, FX revaluation,\nbank postings, VAT settlement, intercompany, revenue recognition, year-end close) are refused\nwith 409, and the message names where the correction belongs, so that documents, payments and\nassets never drift from the ledger. Also 409 when the entry is not posted, is already\nreversed, already has a reversal waiting for approval, or the period of the reversal date is\nclosed; 422 when no fiscal period covers that date or the reason is missing.",
        "operationId": "reverse_entry_v1_journal_entries__entry_id__reverse_post",
        "parameters": [
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Journal entry id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Entry Id"
            },
            "description": "Journal entry id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReverseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JournalEntryOut"
                }
              }
            }
          },
          "202": {
            "description": "The reversal needs a second person: the approval request (`object_type` `journal_reversal`). The entry stays posted until it is approved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/journal-entries/{entry_id}/submit": {
      "post": {
        "tags": [
          "journals"
        ],
        "summary": "Submit a draft entry",
        "description": "Submit a draft entry through the approval policy: it is posted if the policy allows it\nfor the caller (`result.status` `posted`), otherwise it becomes `pending_approval` with an\n`approval_id` for a second person. Only drafts can be submitted (409 otherwise). A policy\ndecision `deny` answers 403. A key without the post scope always sends it to approval.",
        "operationId": "submit_entry_v1_journal_entries__entry_id__submit_post",
        "parameters": [
          {
            "name": "entry_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Journal entry id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Entry Id"
            },
            "description": "Journal entry id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/lead-forms": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List website forms",
        "description": "The forms on the organization's websites that create leads, by name, with their public\nkey, their own page and how many leads each created.",
        "operationId": "list_lead_forms_v1_lead_forms_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's forms (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this company's forms (code or id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LeadFormOut"
                  },
                  "title": "Response List Lead Forms V1 Lead Forms Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Set up a website form",
        "description": "A form for a website: whoever fills it in becomes a lead of the company, owned by\n`owner_user_id`, with the source `web_form`. Link to or embed its own page (`page_path`), or\nsend your website's own form to it (docs/erp/leads.md). A person's setting: 403\n`lead_form_agent` for an agent. Needs an `Idempotency-Key`.",
        "operationId": "create_lead_form_v1_lead_forms_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadFormInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadFormOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/lead-forms/{form_id}": {
      "patch": {
        "tags": [
          "crm"
        ],
        "summary": "Change or switch off a website form",
        "description": "Its name, owner, language, websites, thank-you text or page to go to; `active: false`\nswitches it off (its key then answers 404). A form is never deleted: its leads name it.",
        "operationId": "update_lead_form_v1_lead_forms__form_id__patch",
        "parameters": [
          {
            "name": "form_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the form (`GET /v1/lead-forms`).",
              "examples": [
                "9f2a3b4c-5d6e-4f7a-8b8c-9d0e1f2a3b4c"
              ],
              "title": "Form Id"
            },
            "description": "Id of the form (`GET /v1/lead-forms`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadFormUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadFormOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/lead-forms/{form_id}/new-key": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Give a website form a new key",
        "description": "A new public key, for a form whose key is abused: the old key stops working at once, so the\nwebsite must get the new one.",
        "operationId": "new_lead_form_key_v1_lead_forms__form_id__new_key_post",
        "parameters": [
          {
            "name": "form_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the form (`GET /v1/lead-forms`).",
              "examples": [
                "9f2a3b4c-5d6e-4f7a-8b8c-9d0e1f2a3b4c"
              ],
              "title": "Form Id"
            },
            "description": "Id of the form (`GET /v1/lead-forms`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadFormOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/leads": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List leads",
        "description": "The people who may become customers, the newest first, with their status, source and\nowner. Read-only.",
        "operationId": "list_leads_v1_leads_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's leads (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this company's leads (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "converted",
                    "disqualified",
                    "new",
                    "working"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only leads at this status.",
              "title": "Status"
            },
            "description": "Only leads at this status."
          },
          {
            "name": "open_only",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only open leads (new and working).",
              "default": false,
              "title": "Open Only"
            },
            "description": "Only open leads (new and working)."
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "advertising",
                    "email",
                    "event",
                    "hubspot",
                    "import",
                    "other",
                    "partner",
                    "phone",
                    "referral",
                    "web_form"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only leads from this source.",
              "title": "Source"
            },
            "description": "Only leads from this source."
          },
          {
            "name": "owner_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this person's.",
              "title": "Owner User Id"
            },
            "description": "Only this person's."
          },
          {
            "name": "unassigned",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only the leads nobody owns.",
              "default": false,
              "title": "Unassigned"
            },
            "description": "Only the leads nobody owns."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the name, company, e-mail or number.",
              "title": "Q"
            },
            "description": "Text in the name, company, e-mail or number."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, the newest first.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LeadOut"
                  },
                  "title": "Response List Leads V1 Leads Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Add a lead",
        "description": "A person who may become a customer: name, company, e-mail, phone, where they came from\n(`source`) and who works on them (`owner_user_id`); it starts `new`. An agent may add one.\nWebsite forms add theirs themselves. Needs an `Idempotency-Key`.",
        "operationId": "create_lead_v1_leads_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/leads/summary": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Count leads by status",
        "description": "How many leads the company has at each status, where the open ones came from, how many\nnobody owns, and how many were converted in the last 30 days.",
        "operationId": "lead_summary_v1_leads_summary_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Code (or id) of the company.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Code (or id) of the company."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadSummary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/leads/{lead_id}": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get a lead",
        "description": "One lead; a converted one names its customer, contact and deal.",
        "operationId": "get_lead_v1_leads__lead_id__get",
        "parameters": [
          {
            "name": "lead_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the lead (`GET /v1/leads`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Lead Id"
            },
            "description": "Id of the lead (`GET /v1/leads`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "crm"
        ],
        "summary": "Change a lead",
        "description": "Change what the request names: its status (`new`, `working`, or `disqualified` with a\nreason), owner, source or the person's details (`\"\"` clears a text field but the last name).\nThe audit trail records which fields changed, never their values. 409 `lead_converted` for a\nconverted lead, `lead_erased` for an erased one.",
        "operationId": "update_lead_v1_leads__lead_id__patch",
        "parameters": [
          {
            "name": "lead_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the lead (`GET /v1/leads`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Lead Id"
            },
            "description": "Id of the lead (`GET /v1/leads`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/leads/{lead_id}/convert": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Convert a lead into a customer, contact and deal",
        "description": "In one step: the customer (an existing one, `party`, or a new one, `customer`, created with\nevery check a new customer has), the person as its contact (new, or an existing one,\n`contact_id`) and, unless `create_deal` is false, a deal with them owned by the lead's owner,\nat `qualified` by default, whose first note is what the person wrote. The lead then names all\nthree and is final. 409 `lead_converted`, `lead_disqualified` or `lead_erased`. A new customer\nwithout a country takes the lead's, else the company's; its currency and language follow\nthe country (see creating a customer). Needs an `Idempotency-Key`.",
        "operationId": "convert_lead_v1_leads__lead_id__convert_post",
        "parameters": [
          {
            "name": "lead_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the lead (`GET /v1/leads`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Lead Id"
            },
            "description": "Id of the lead (`GET /v1/leads`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeadConvert"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/leads/{lead_id}/erase": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Erase a lead's personal data",
        "description": "Empty the lead's name, company, role, e-mail, phone and message for good (the person asked\nto be forgotten). The row stays with its number, status and source; it cannot be undone. A\nconverted lead's customer and contact are erased on their own. A person's decision: 403\n`lead_erase_agent` for an agent. 409 `lead_erased` if already erased.",
        "operationId": "erase_lead_v1_leads__lead_id__erase_post",
        "parameters": [
          {
            "name": "lead_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the lead (`GET /v1/leads`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Lead Id"
            },
            "description": "Id of the lead (`GET /v1/leads`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeadOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/leases": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Enter a lease",
        "description": "Enter a lease the company holds as a lessee: a draft until it is activated, or, with an\n`exemption` (short-term, low value), a lease that is only listed and whose bills are expensed.\n\nAccounts not named are the company's accounts with the lease roles (the IFRS and US charts\nhave them; a local chart such as the Swiss KMU names them). A US GAAP company classifies the\nlease (`classification`, default `operating`: one straight-line lease cost a period on the\n`lease_cost` account); under IFRS every lease is a finance lease. The answer has the schedule:\nthe liability at commencement (the present value of the payments at the effective annual\n`rate_percent`), interest and payments month by month, and the asset's straight-line\ndepreciation (an operating lease: the lease cost and the asset's reduction). Refused: 409\n`lease_exists` when the code exists in the company; 422 `lease_local_framework` (a company\nunder local rules expenses its leases), `lease_operating_ifrs` (an operating lease outside\nUS GAAP), `lease_term_frequency` (a term that is no multiple of the payment interval),\n`lease_not_short_term`, `lease_account_type`, `lease_accounts_differ`,\n`lease_account_currency` and `role_account_missing` (no account named and none with the role).",
        "operationId": "create_lease_v1_leases_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LeaseInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/leases/{lease}": {
      "get": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Get a lease and its schedule",
        "description": "One lease with its terms, accounts, changes of payments, the entries that activated and\nended it, its schedule month by month (which months are booked) and its position at `as_of`,\nwith the liability split into current (principal due within 12 months) and non-current.\nRefused with 404 for an unknown lease.",
        "operationId": "get_lease_v1_leases__lease__get",
        "parameters": [
          {
            "name": "lease",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Lease id (`GET /v1/entities/{entity}/leases`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Lease"
            },
            "description": "Lease id (`GET /v1/entities/{entity}/leases`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The date of the position figures, ISO 8601. Default: today where the company is.",
              "examples": [
                "2026-09-30"
              ],
              "title": "As Of"
            },
            "description": "The date of the position figures, ISO 8601. Default: today where the company is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/leases/{lease}/activate": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Activate a lease",
        "description": "Book the commencement entry of a draft lease, dated at the commencement date, through the\napproval policy: Dr right-of-use asset (functional currency, at that day's rate) / Cr lease\nliability (lease currency), and the initial direct costs and payments made before\ncommencement from `credit_account` into the asset. The lease is `pending` while the entry\nwaits for approval and `active` once it is posted; a rejection makes it a draft again.\nRefused: 404 for an unknown lease; 409 `lease_not_draft`, `period_closed`; 422\n`lease_credit_account_missing`, `fx_rate_missing`.",
        "operationId": "activate_lease_v1_leases__lease__activate_post",
        "parameters": [
          {
            "name": "lease",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Lease id (`GET /v1/entities/{entity}/leases`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Lease"
            },
            "description": "Lease id (`GET /v1/entities/{entity}/leases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/leases/{lease}/changes": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "Change a lease's payments",
        "description": "Remeasure an active lease for new payments from the first day of a lease month on (an\nindex increase): the liability becomes the present value of the remaining payments at the\noriginal rate, and the right-of-use asset changes by the same amount, in one entry dated that\nday through the approval policy. Refused: 409 `lease_not_active`, `lease_change_booked` (that\nmonth is booked already), `lease_change_later` (a change from that month or later exists);\n422 `lease_change_date` (not the first day of a lease month), `lease_change_nothing`,\n`lease_change_too_large` (a decrease beyond what is left of the asset).",
        "operationId": "change_lease_v1_leases__lease__changes_post",
        "parameters": [
          {
            "name": "lease",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Lease id (`GET /v1/entities/{entity}/leases`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Lease"
            },
            "description": "Lease id (`GET /v1/entities/{entity}/leases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChangeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/leases/{lease}/terminate": {
      "post": {
        "tags": [
          "fixed assets"
        ],
        "summary": "End a lease",
        "description": "End an active lease on the last day of a lease month: derecognise the liability left and\nthe right-of-use asset (cost and accumulated depreciation), the difference a gain or a loss\n(`result_account`, else the company's gain or loss on disposal of assets), through the\napproval policy. The lease is `terminated` once the entry is posted. Refused: 409\n`lease_not_active`, `lease_change_pending` (a change of payments waits for approval: decide\nit first), `lease_end_unbooked` (post the lease entries up to the day first),\n`lease_end_booked_after`; 422 `lease_end_date` (not the last day of a lease month).",
        "operationId": "terminate_lease_v1_leases__lease__terminate_post",
        "parameters": [
          {
            "name": "lease",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Lease id (`GET /v1/entities/{entity}/leases`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Lease"
            },
            "description": "Lease id (`GET /v1/entities/{entity}/leases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TerminateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmitResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/mandates/{mandate_id}/account": {
      "put": {
        "tags": [
          "direct debits"
        ],
        "summary": "Change the debtor account of a mandate",
        "description": "The customer's account holder name or BIC apply at once; a new IBAN waits for a second\nperson (`pending_change`), and nothing is collected under the mandate meanwhile. Once\napproved, the next collection under a used mandate tells the bank of the change. 409 when the\nmandate is not active or expired, or a change of it already waits; 403 for an agent.",
        "operationId": "change_mandate_account_v1_mandates__mandate_id__account_put",
        "parameters": [
          {
            "name": "mandate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Mandate id (`GET /v1/entities/{entity}/customers/{party}/mandates`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Mandate Id"
            },
            "description": "Mandate id (`GET /v1/entities/{entity}/customers/{party}/mandates`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MandateAccountInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MandateOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/mandates/{mandate_id}/revoke": {
      "post": {
        "tags": [
          "direct debits"
        ],
        "summary": "Revoke a mandate",
        "description": "The customer cancelled the mandate: nothing more is collected under it. Collections made\nalready stay; reverse a receipt that is not to be sent. 409 when it is not active or a\nchange of it waits for approval; 403 for an agent.",
        "operationId": "revoke_mandate_v1_mandates__mandate_id__revoke_post",
        "parameters": [
          {
            "name": "mandate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Mandate id (`GET /v1/entities/{entity}/customers/{party}/mandates`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Mandate Id"
            },
            "description": "Mandate id (`GET /v1/entities/{entity}/customers/{party}/mandates`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MandateOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/me": {
      "get": {
        "tags": [
          "organization"
        ],
        "summary": "Me",
        "description": "Who the credential is: actor type (`human` or `agent`), id, name, organization and scopes.\n\n`auth` says whether the request was authenticated with an `api_key` or a web UI `session`.\n`locale` is the UI language of a signed-in person and null for API keys. Any valid\ncredential may call this; it is the quickest check that a key works and what it may do.",
        "operationId": "me_v1_me_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ]
      },
      "patch": {
        "tags": [
          "organization"
        ],
        "summary": "Update my preferences",
        "description": "Change your own preferences: the web UI language (`locale`; null follows the browser).\n\nOnly the fields sent change. Preferences belong to people signed in to the web UI: a call\nwith an API key answers 409. Returns the updated identity, as `GET /v1/me`.",
        "operationId": "update_me_v1_me_patch",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Preferences"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/me/approver-acknowledgement": {
      "post": {
        "tags": [
          "approvals"
        ],
        "summary": "Confirm that my approvals are recorded in my name",
        "description": "A person an administrator named an approver confirms, once, that their approvals and\nrejections are recorded in their name for the company's auditor; they decide nothing before\n(409 `approver_acknowledgement_needed`). `GET /v1/me` says when it is due\n(`approver_acknowledgement_needed`). Recorded in the audit trail (`approver.acknowledge`);\nnothing changes when it is not due. 409 `approver_not_a_person` for an API key or agent.",
        "operationId": "acknowledge_approver_v1_me_approver_acknowledgement_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/me/mailbox": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get your mailbox link",
        "description": "Whether this system offers the Google link (`available`, with the OAuth `client_id` and\n`scopes` the browser asks for consent with) and your own link: the account, whether Google\nallowed mail and calendar, how far each was read and the last error. An API key has no\nmailbox (`linked` false).",
        "operationId": "get_mailbox_v1_me_mailbox_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MailboxStatus"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "delete": {
        "tags": [
          "crm"
        ],
        "summary": "Unlink your mailbox",
        "description": "Unlink your Google account: Google takes the access back and nothing more is read. What\nwas logged stays on the timelines (an activity is never deleted).",
        "operationId": "unlink_mailbox_v1_me_mailbox_delete",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MailboxStatus"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/me/mailbox/google": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Link your Google account",
        "description": "Link your Gmail and Google Calendar with the one-time `code` Google's consent popup gave\nthe browser. From then on your e-mails and meetings with the contact of an open deal, or with\na customer or one of its contacts, are logged on that deal's or customer's timeline (the last\n30 days first). Read-only at Google: nothing is ever sent. Linking again replaces the link.\n409 for an API key, in a test copy, when Google refuses the code, or when this system does not\noffer the link; 422 when Google was allowed neither mail nor calendar.",
        "operationId": "link_google_v1_me_mailbox_google_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinkInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MailboxStatus"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/me/mailbox/sync": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Read your mailbox now",
        "description": "Read your linked mailbox and calendar now (a job reads every linked one every 15\nminutes) and log what is about deals and customers. Returns how many e-mails and meetings\nwere read and how many were newly logged. 409 when nothing is linked or Google stopped\naccepting the link (then link again).",
        "operationId": "sync_mailbox_v1_me_mailbox_sync_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncOut"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/me/notification-settings": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "Get which notifications come by e-mail",
        "description": "The kinds of notification you also get by e-mail (none until you choose), to your sign-in\naddress, gathered into one message per sending, and whether this system sends e-mail at all\n(`email_available`: never from a test copy). 409 for an API key or an agent.",
        "operationId": "get_notification_settings_v1_me_notification_settings_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "notifications"
        ],
        "summary": "Choose which notifications come by e-mail",
        "description": "Choose the kinds you also get by e-mail; an empty list stops every e-mail. What is already\nin the centre is not e-mailed afterwards. 409 for an API key or an agent.",
        "operationId": "put_notification_settings_v1_me_notification_settings_put",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NotificationSettings"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationSettingsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/me/notifications": {
      "get": {
        "tags": [
          "notifications"
        ],
        "summary": "List your notifications",
        "description": "Your notification centre, the newest first: tasks given to you, due or overdue, deals of\nyours assigned, won or lost by someone else, your approval requests decided, and (for\nadministrators) a webhook stopped because it kept failing. Reading it also writes the task\nreminders that came due since (a task of yours reminds you the day it is due and once more\nwhen that day passed; one whose day passed more than 7 days ago no longer does). `unread` is\nthe count of unread ones, `approvals_waiting` the approval requests you may decide now. A key\nor an agent of a person (an AI assistant) reads that person's list, without marking anything\nread; one the system issued has none: the list is empty.",
        "operationId": "list_notifications_v1_me_notifications_get",
        "parameters": [
          {
            "name": "unread",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only the unread ones.",
              "default": false,
              "title": "Unread"
            },
            "description": "Only the unread ones."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "Most returned, the newest first.",
              "default": 50,
              "title": "Limit"
            },
            "description": "Most returned, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationList"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/me/notifications/read": {
      "post": {
        "tags": [
          "notifications"
        ],
        "summary": "Mark notifications read",
        "description": "Mark the given notifications of yours (`ids`), or every unread one (`all`), read. Returns\nyour list as `GET /v1/me/notifications` does. 409 for an API key or an agent.",
        "operationId": "read_notifications_v1_me_notifications_read_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarkRead"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationList"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/me/passkeys": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "List my passkeys",
        "description": "The signed-in person's passkeys, oldest first. They open every organization the person\nis a user of. Only for a web UI session (403 for an API key).",
        "operationId": "my_passkeys_v1_me_passkeys_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/PasskeyOut"
                  },
                  "type": "array",
                  "title": "Response My Passkeys V1 Me Passkeys Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ]
      },
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Add a passkey",
        "description": "Record the passkey the browser created for `POST /v1/me/passkeys/options`, named `name`.\nNeeds a passkey touch within five minutes (403 `passkey_step_up`); 403 for an answer that\ndoes not verify or a used or expired question; 409 for a passkey already registered.\nRecorded as a security event (`passkey.add`).",
        "operationId": "add_passkey_v1_me_passkeys_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PasskeyAnswer"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasskeyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/me/passkeys/options": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Start adding a passkey",
        "description": "The question to create one more passkey, for another device: create it in the browser\nwith these options and send the answer to `POST /v1/me/passkeys`. Needs a passkey touch\nwithin five minutes (403 `passkey_step_up`); only for a web UI session.",
        "operationId": "add_passkey_options_v1_me_passkeys_options_post",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasskeyStep"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/me/passkeys/{passkey_id}": {
      "delete": {
        "tags": [
          "users"
        ],
        "summary": "Remove a passkey",
        "description": "Remove one of the signed-in person's passkeys (a lost or replaced device). Needs a passkey\ntouch within five minutes (403 `passkey_step_up`); 409 for the last one (`passkey_last`:\nadd another first); 404 for a passkey that is not theirs. Recorded as a security event\n(`passkey.remove`). The response has no body.",
        "operationId": "remove_passkey_v1_me_passkeys__passkey_id__delete",
        "parameters": [
          {
            "name": "passkey_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Passkey id (`GET /v1/me/passkeys`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Passkey Id"
            },
            "description": "Passkey id (`GET /v1/me/passkeys`)."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/me/record-access": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Which sales records you see",
        "description": "Whether you see every sales record, your team's or your own, and whose.",
        "operationId": "my_record_access_v1_me_record_access_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MyRecordAccess"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/opportunities": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List opportunities",
        "description": "The deals of the pipeline, the newest first, each with its weighted amount. Someone who\nsees only their own or their team's records gets only those deals. Read-only.",
        "operationId": "list_opportunities_v1_opportunities_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's deals (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's deals (code or id)."
          },
          {
            "name": "stage",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "lead",
                    "lost",
                    "negotiation",
                    "proposal",
                    "qualified",
                    "won"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only deals at this stage.",
              "title": "Stage"
            },
            "description": "Only deals at this stage."
          },
          {
            "name": "open",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only open deals (not won or lost).",
              "default": false,
              "title": "Open"
            },
            "description": "Only open deals (not won or lost)."
          },
          {
            "name": "party_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's deals.",
              "title": "Party Id"
            },
            "description": "Only this customer's deals."
          },
          {
            "name": "owner_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this owner's deals.",
              "title": "Owner User Id"
            },
            "description": "Only this owner's deals."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "expansion",
                    "new_business",
                    "renewal"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only deals of this kind (`renewal`: the renewal deals of subscriptions).",
              "title": "Kind"
            },
            "description": "Only deals of this kind (`renewal`: the renewal deals of subscriptions)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many deals, the newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many deals, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OpportunityOut"
                  },
                  "title": "Response List Opportunities V1 Opportunities Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Create an opportunity",
        "description": "A deal in an entity's pipeline, with a customer (`party`) or with a prospect that is not a\ncustomer yet (`prospect_name`). It gets the next number of the entity (`OPP-000001`) and the\nstage's default probability unless `probability` is given. Nothing is posted. 404 for an\nunknown entity or customer (a vendor is not one); 422 for an owner who is not a person of the\norganization. Needs an `Idempotency-Key`.",
        "operationId": "create_opportunity_v1_opportunities_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpportunityInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpportunityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/opportunities/pipeline": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get the pipeline of an entity",
        "description": "The open deals by stage and currency (count, amount, amount weighted by probability), the\ndeals won and lost in the range, and the entity's open and overdue tasks. Amounts are summed\nper currency and never converted. Read-only.",
        "operationId": "get_pipeline_v1_opportunities_pipeline_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code (or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code (or id)."
          },
          {
            "name": "closed_from",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First close day of the won and lost deals; default 1 January.",
              "title": "Closed From"
            },
            "description": "First close day of the won and lost deals; default 1 January."
          },
          {
            "name": "closed_to",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last close day of the won and lost deals; default today.",
              "title": "Closed To"
            },
            "description": "Last close day of the won and lost deals; default today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pipeline"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/opportunities/{opportunity_id}": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get an opportunity",
        "description": "One deal (its timeline: `GET /v1/activities?opportunity_id=`). 404 when it does not\nexist.",
        "operationId": "get_opportunity_v1_opportunities__opportunity_id__get",
        "parameters": [
          {
            "name": "opportunity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the opportunity (`GET /v1/opportunities`).",
              "examples": [
                "3f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c"
              ],
              "title": "Opportunity Id"
            },
            "description": "Id of the opportunity (`GET /v1/opportunities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpportunityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "crm"
        ],
        "summary": "Change an opportunity",
        "description": "Change what the body names (omitted fields keep their value, `\"\"` empties a text field),\nfor example the customer once the prospect is set up as one (`party`). The stage changes\nthrough `POST .../stage`. 409 for a won deal (only `owner_user_id` and `next_step` change)\nand for the probability of a won or lost one; the change is audited with the previous\nvalues.",
        "operationId": "update_opportunity_v1_opportunities__opportunity_id__patch",
        "parameters": [
          {
            "name": "opportunity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the opportunity (`GET /v1/opportunities`).",
              "examples": [
                "3f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c"
              ],
              "title": "Opportunity Id"
            },
            "description": "Id of the opportunity (`GET /v1/opportunities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpportunityUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpportunityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/opportunities/{opportunity_id}/stage": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Move an opportunity to a stage",
        "description": "Move a deal to an open stage, to `won` (it needs a customer: 409 for a prospect; final from\nthen on) or to `lost` (with `lost_reason`), or reopen a lost deal. `won` and `lost` set the\nprobability to 100 and 0 and the close day (`on`, default today). The deal's timeline gets a\n`stage_change` activity with the `note`. 409 for a won deal or the stage it is at. Needs an\n`Idempotency-Key`.",
        "operationId": "set_opportunity_stage_v1_opportunities__opportunity_id__stage_post",
        "parameters": [
          {
            "name": "opportunity_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the opportunity (`GET /v1/opportunities`).",
              "examples": [
                "3f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c"
              ],
              "title": "Opportunity Id"
            },
            "description": "Id of the opportunity (`GET /v1/opportunities`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StageInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OpportunityOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/organization": {
      "get": {
        "tags": [
          "organization"
        ],
        "summary": "Get Organization",
        "description": "The organization the credential belongs to: id, name, creation time and whether the\ndefault approval policy or the organization's own applies (`approval_policy`; the policy\nitself is `GET /v1/approval-policy`).",
        "operationId": "get_organization_v1_organization_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "organization"
        ],
        "summary": "Rename the organization",
        "description": "Rename the organization and return it. Only a human with the admin scope may do this\n(agent keys and other scopes get 403); a blank name is refused with 422, an omitted or\nunchanged name changes nothing. The change is an audit event, `org.update`. The approval\npolicy has its own resource, `/v1/approval-policy`.",
        "operationId": "update_organization_v1_organization_patch",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrganizationUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/payment-exports": {
      "get": {
        "tags": [
          "swiss payments"
        ],
        "summary": "List payment files",
        "description": "The payment files released for an entity, newest first (at most 100), each with its\nmessage id, format, SHA-256, payment numbers and control sum: pain.001 files of payments and\npain.008 files of direct debit collections. The file itself is\n`GET /v1/payment-exports/{id}/file`.",
        "operationId": "list_exports_v1_payment_exports_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "credit_transfer",
                    "direct_debit"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`credit_transfer`: the pain.001 files of payments; `direct_debit`: the pain.008 files of SEPA direct debits (ADR-0076). Default both.",
              "title": "Kind"
            },
            "description": "`credit_transfer`: the pain.001 files of payments; `direct_debit`: the pain.008 files of SEPA direct debits (ADR-0076). Default both."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PaymentExportOut"
                  },
                  "title": "Response List Exports V1 Payment Exports Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "swiss payments"
        ],
        "summary": "Release payments as a pain.001 file",
        "description": "Release approved outgoing payments as an SPS pain.001.001.09 file.\n\nOnly payments that passed the approval policy (status ``posted``) qualify, each\nexactly once; agents cannot release payment files (403). The file, its SHA-256 and\nthe releasing person are recorded, and the payments are marked as sent. Refuses with 422\nwhen a payment cannot be released (see `problems` in `GET /v1/payments`), is listed twice\nor the execution date is in the past, 404 for a payment of another entity, and 409 when\na payment was already sent, and in a test copy, which makes no payment file (ADR-0039).\nDownload the file with `GET /v1/payment-exports/{id}/file`.",
        "operationId": "export_payments_v1_payment_exports_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentExportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/payment-exports/{export_id}": {
      "get": {
        "tags": [
          "swiss payments"
        ],
        "summary": "Get a payment file",
        "description": "One released payment file's record: message id, filename, SHA-256, number of\npayments, control sum, who released it and the execution date of each payment. 404 when\nit does not exist.",
        "operationId": "get_export_v1_payment_exports__export_id__get",
        "parameters": [
          {
            "name": "export_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Payment export id (`POST /v1/payment-exports`, `GET /v1/payment-exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Export Id"
            },
            "description": "Payment export id (`POST /v1/payment-exports`, `GET /v1/payment-exports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentExportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/payment-exports/{export_id}/file": {
      "get": {
        "tags": [
          "swiss payments"
        ],
        "summary": "Download a payment file",
        "description": "The pain.001 (or pain.008) file exactly as released, as an XML attachment. Its SHA-256\nis in the export record and in the `X-Content-SHA256` response header. 404 when the export\ndoes not exist.",
        "operationId": "export_file_v1_payment_exports__export_id__file_get",
        "parameters": [
          {
            "name": "export_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Payment export id (`POST /v1/payment-exports`, `GET /v1/payment-exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Export Id"
            },
            "description": "Payment export id (`POST /v1/payment-exports`, `GET /v1/payment-exports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The pain.001 or pain.008 file.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/payments": {
      "get": {
        "tags": [
          "swiss payments"
        ],
        "summary": "List payments",
        "description": "Payments of an entity, newest first, with their pain.001 payment type (`D` domestic\nor `S` SEPA), release status and the problems that block releasing each payment (for\nexample a draft vendor, unconfirmed bank details or a missing IBAN). Use it to choose the\npayments to pass to `POST /v1/payment-exports`.",
        "operationId": "list_payments_v1_payments_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code, e.g. `CH01` (`GET /v1/entities`).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code, e.g. `CH01` (`GET /v1/entities`)."
          },
          {
            "name": "direction",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "incoming",
                    "outgoing"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`outgoing` (default): payments to vendors; `incoming`: receipts from customers.",
              "default": "outgoing",
              "title": "Direction"
            },
            "description": "`outgoing` (default): payments to vendors; `incoming`: receipts from customers."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "draft",
                    "pending_approval",
                    "posted",
                    "rejected",
                    "reversed"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Payment status: `draft`, `pending_approval`, `posted`, `rejected` or `reversed`.",
              "title": "Status"
            },
            "description": "Payment status: `draft`, `pending_approval`, `posted`, `rejected` or `reversed`."
          },
          {
            "name": "execution",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "open",
                    "sent"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`open`: not yet in a payment file; `sent`: released in a payment file. Default: both.",
              "title": "Execution"
            },
            "description": "`open`: not yet in a payment file; `sent`: released in a payment file. Default: both."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "description": "Most payments returned, up to 1000.",
              "default": 200,
              "title": "Limit"
            },
            "description": "Most payments returned, up to 1000."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PaymentRow"
                  },
                  "title": "Response List Payments V1 Payments Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Record a payment or receipt",
        "description": "Record a payment (to a vendor) or a receipt (from a customer) and allocate it to open\ndocuments; realised FX is posted. An outgoing payment awaits the bank's execution on the\npayments-in-transit account until its bank statement line is matched, unless it is recorded\nas already `executed` by the bank (ADR-0060); a receipt goes to the bank. The `allocations`\nand `on_account` must add up to `amount`; each allocation settles one posted document of the\nparty in the payment's currency. `on_account` keeps the rest on the party's account (an\noverpayment, an advance, or a payment of nothing yet): an open item of the party in the\naging, the statement and its balances, booked at the payment's rate, applied later with\n`POST /v1/applications`. The payment's entry goes through the approval policy: the result's\n`submit.policy` is `allow` (posted and numbered) or `require_approval` (status\n`pending_approval`); `deny` answers 403. Refuses with 422 when the amounts do not add up, a\ndocument cannot be settled by this payment (wrong party, kind, status or currency), an\nallocation exceeds the open amount, a cash discount is not allowed or a receipt is dated\nafter today (`receipt_in_future`, an outgoing one `payment_in_future`) or before a document\nit settles (`payment_before_document`), and with 404 for an unknown document, party or\naccount. All or nothing: a refused payment leaves nothing behind. A payment that takes its\nbank account below zero in the books on its date is recorded, with a `warnings` line and its\n`warning_reasons` by code (the money may be there and not booked yet).",
        "operationId": "create_payment_v1_payments_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/payments/{payment_id}": {
      "get": {
        "tags": [
          "payments"
        ],
        "summary": "Get a payment",
        "description": "One payment or receipt by id: its direction, party, amount, currency, bank account,\nstatus and journal entry. 404 when it does not exist. The release status and problems\nblocking a payment file are in `GET /v1/payments`.",
        "operationId": "get_payment_v1_payments__payment_id__get",
        "parameters": [
          {
            "name": "payment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Payment id, as returned by `POST /v1/payments` or `GET /v1/payments`.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Payment Id"
            },
            "description": "Payment id, as returned by `POST /v1/payments` or `GET /v1/payments`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/payments/{payment_id}/refund": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Pay back an amount on account",
        "description": "Pay back part or all of what a posted payment keeps on account: a customer's overpayment\npaid back to the customer, or an advance paid to a vendor that the vendor pays back. The\nrefund is a payment the other way (`outgoing` to the customer, `incoming` from the vendor)\nwhose entry relieves the payment's line on account at the share of what it booked, the\ndifference to the bank at the refund's rate being realised FX, so the amount on account shrinks\nin the aging, the statement and the balances by what was paid back. It goes through the\napproval policy (`submit.policy`); waiting, it reserves its amount. It is reversed like any\npayment (`POST /v1/payments/{payment_id}/reverse`), and the payment it pays back is not\nreversed while it stands (`payment_on_account_refunded`).\n\nRefused with 422: more than is left on account (`more_than_left_to_apply`), dated before the\npayment or its latest application or refund (`application_before_document`,\n`application_before_settlement`), a refund received dated after today (`receipt_in_future`),\na payment with nothing on account (`nothing_to_apply`) or one that is itself a refund kept on\naccount, which is applied to the credit note it pays instead (`refund_not_on_account`); 409\nwhen a reversal of the payment waits or the period is closed; 404 for an unknown payment.",
        "operationId": "refund_on_account_v1_payments__payment_id__refund_post",
        "parameters": [
          {
            "name": "payment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Payment id, as returned by `POST /v1/payments` or `GET /v1/payments`.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Payment Id"
            },
            "description": "Payment id, as returned by `POST /v1/payments` or `GET /v1/payments`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OnAccountRefundInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/payments/{payment_id}/reverse": {
      "post": {
        "tags": [
          "payments"
        ],
        "summary": "Reverse a payment or receipt",
        "description": "Reverse a posted payment or receipt: an entry of its own, dated `on` (default today, or the\npayment date of a payment scheduled later; not before the payment, in an open period),\nundoes the payment's entry line by line (bank, receivables or payables at the documents'\nhistorical rates, cash discount with its VAT correction, realised FX difference), so the\nbooks are as before it to the cent. The `reason`\nis required (at most 500 characters) and kept on the entry and in the audit trail.\n\nThe reversal goes through the approval policy as the payment did (`post`, with its source and\namount). `status` `reversed`: it is posted, the payment and its allocations are `reversed` and\nthe invoices, bills or credit notes it settled are open again by what it settled. `status`\n`posted`: the reversal waits for a second person (`reversal.approval_id`, decided with\n`POST /v1/approvals/{approval_id}/approve`, four eyes) and the payment stands until then. A\nreversal asked by an agent, and one of a payment released in a payment file (`released_in`:\nmake sure the bank did not execute it), always waits for a person.\n\nRefused with 409: the payment is not posted (one waiting for approval is rejected instead),\nalready reversed or its reversal already waits; it is matched to a bank statement line (undo\nthe match on that line first, `POST /v1/bank-lines/{line_id}/unmatch`, which reverses the\npayment the match recorded); the period of the date is closed. 422: no period covers the date,\nthe date is before the payment's, or the reason is missing. 404: unknown payment.",
        "operationId": "reverse_payment_v1_payments__payment_id__reverse_post",
        "parameters": [
          {
            "name": "payment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Payment id, as returned by `POST /v1/payments` or `GET /v1/payments`.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Payment Id"
            },
            "description": "Payment id, as returned by `POST /v1/payments` or `GET /v1/payments`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PaymentReverseRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PaymentReversalResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/people": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "List the people to choose from",
        "description": "The active people of the organization (id, email, name) ordered by name, to choose the\nowner of a deal or a close task from. Any credential with the read scope may list them;\ninvitations, scopes and their management are `GET /v1/users` (admin scope).",
        "operationId": "list_people_v1_people_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/Person"
                  },
                  "type": "array",
                  "title": "Response List People V1 People Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/people/{user_id}/record-visibility": {
      "put": {
        "tags": [
          "crm"
        ],
        "summary": "Set which sales records a person sees",
        "description": "`all` (every customer, contact, deal and activity), `team` (the records they or anyone in\na team of theirs own) or `own` (the records they own), from their next request on, on every\nscreen, the REST API and MCP alike; their keys and the agents they use see the same. Finance\ndocuments and the ledger are not sales records: rights (scopes) govern them. Audited.",
        "operationId": "set_record_visibility_v1_people__user_id__record_visibility_put",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the person (`GET /v1/people`).",
              "examples": [
                "8b1f2c3d-4e5f-4a6b-9c7d-8e9f0a1b2c3d"
              ],
              "title": "User Id"
            },
            "description": "Id of the person (`GET /v1/people`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VisibilityInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonAccess"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/close": {
      "post": {
        "tags": [
          "close"
        ],
        "summary": "Close a period",
        "description": "Lock the period once every check passes. Humans only (policy).\n\nEvaluates the close checklist and, when no check fails, sets the period to closed so\nnothing can be posted into it; the response is the checklist afterwards. Reopen with\n`POST /v1/periods/{period_id}/reopen`. Refused: 403 when the policy or the caller's scopes\ndo not allow closing periods; 409 when the period is already closed or a check fails\n(the message names the failing check ids). The entity's own close tasks do not hold the\nclose (the checks decide it, ADR-0034): a task not done by then stays not done, and is\nrecorded only after the period is reopened.",
        "operationId": "close_period_v1_periods__period_id__close_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Checklist"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/close-checklist": {
      "get": {
        "tags": [
          "close"
        ],
        "summary": "Get the close checklist of a period",
        "description": "Evaluate the conditions for closing a period, without changing anything.\n\nEach check has a status of `pass`, `fail`, `warn` or `n/a`: pending approvals, drafts,\ndepreciation, FX revaluation, deferred tax, receivables and payables control accounts,\nbank reconciliation and balances, trial balance, ledger hash chain and earlier periods.\n`ready` is true when no check fails (warnings do not block).",
        "operationId": "close_checklist_v1_periods__period_id__close_checklist_get",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Checklist"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/periods/{period_id}/close-status": {
      "get": {
        "tags": [
          "close tracker"
        ],
        "summary": "Get where the close of a period stands",
        "description": "The close of one period: each step (recurring invoices, depreciation, FX revaluation,\ndeferred tax, the checklist, the close) and each of the entity's own tasks with the day it is\ndue and whether it is `done`, `open`, `overdue` or `n/a`, who did a task and with what\nevidence, the checklist's failing checks, and what the scheduled close job did for the period\n(`job_log`). The close checklist decides every step and every task linked to a check, so this\nnever says done over a failing check. Read-only.",
        "operationId": "get_close_status_v1_periods__period_id__close_status_get",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "as_of",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day `overdue` is judged on (ISO 8601); default: today where the entity is.",
              "examples": [
                "2026-10-02"
              ],
              "title": "As Of"
            },
            "description": "The day `overdue` is judged on (ISO 8601); default: today where the entity is."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CloseStatus"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/periods/{period_id}/close-tasks/{task_id}/complete": {
      "post": {
        "tags": [
          "close tracker"
        ],
        "summary": "Record that a close task was done",
        "description": "Record that a person did the task for the period, with what shows it (`evidence`). **A\nperson's** act (`manage_close`): the record is evidence and is never deleted, only withdrawn.\n409 for a task decided by a close check, a task no longer part of the close, one already\ndone for the period, or a closed period (`close_on_record`: its close stays as it was closed;\nreopen the period to record the task); 404 when the task is not one of the period's entity.\nNeeds an `Idempotency-Key`.",
        "operationId": "complete_close_task_v1_periods__period_id__close_tasks__task_id__complete_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the close task (`GET /v1/entities/{entity}/close-tasks`).",
              "examples": [
                "8e3f4051-6273-4c84-9d95-afb6c7d8e920"
              ],
              "title": "Task Id"
            },
            "description": "Id of the close task (`GET /v1/entities/{entity}/close-tasks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompletionInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskStatus"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/periods/{period_id}/close-tasks/{task_id}/withdraw": {
      "post": {
        "tags": [
          "close tracker"
        ],
        "summary": "Withdraw that a close task was done",
        "description": "Take back a completion, with the reason: it stays on record as withdrawn and the task is\nopen again for the period. **A person's** act (`manage_close`). 409 when the task is not done\nfor the period, or the period is closed (`close_on_record`).",
        "operationId": "withdraw_close_task_v1_periods__period_id__close_tasks__task_id__withdraw_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the close task (`GET /v1/entities/{entity}/close-tasks`).",
              "examples": [
                "8e3f4051-6273-4c84-9d95-afb6c7d8e920"
              ],
              "title": "Task Id"
            },
            "description": "Id of the close task (`GET /v1/entities/{entity}/close-tasks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WithdrawInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskStatus"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/deferred-tax": {
      "post": {
        "tags": [
          "close"
        ],
        "summary": "Run deferred tax for a period",
        "description": "Post the change in deferred tax since the last run (after depreciation).\n\nMeasures the temporary differences of the book that carries deferred tax at the period\nend and posts the movement against the deferred tax liability and asset accounts and the\ndeferred tax expense account, through the approval policy (`submit`; null when there is\nnothing to post). `items` are the per-asset differences and `total` the movement.\nRefused: 409 when deferred tax already ran for the period, when the period has not started\nyet (`period_not_started`), or when depreciation is due but has not run; 422 when no\ntax book of the entity carries deferred tax.",
        "operationId": "run_deferred_tax_v1_periods__period_id__deferred_tax_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunSummary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/depreciation": {
      "post": {
        "tags": [
          "close"
        ],
        "summary": "Run depreciation for a period",
        "description": "Post the period's book depreciation for every active asset in service.\n\nThe asset's fiscal-year amount is spread over the regular periods of the year (evenly\nper month, by days on a week-based calendar) and capped at what is left to depreciate.\nOne entry dated at the period end is posted (Dr depreciation expense / Cr accumulated\ndepreciation per asset) through the approval policy; `submit` is null when nothing is\ndue. Adjustment periods get no depreciation; an asset whose disposal waits for approval\nis skipped (the disposal books its depreciation to its date). On the fiscal year's last\nregular period a run that stands can be made again as a top-up that books only the\ndifference to the year's schedule (what is missing, or the excess taken back). Refused:\n404 for an unknown period; 409 when depreciation already ran for the period (on the last\nperiod: and nothing differs), the period is closed, or it has not started yet\n(`period_not_started`: a period-end run is for the current period or an earlier one).",
        "operationId": "run_depreciation_v1_periods__period_id__depreciation_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunSummary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/fx-revaluation": {
      "post": {
        "tags": [
          "close"
        ],
        "summary": "Run FX revaluation for a period",
        "description": "Revalue open foreign-currency items at the closing ECB rate (auto-reversing).\n\nOpen receivables and payables in a foreign currency and foreign-currency bank accounts\nare remeasured at the period-end rate. The unrealised difference is posted at the period\nend (against the unrealised FX account) through the approval policy and reversed on the\nfirst day of the next period once posted. `items` lists each remeasured item with its\n`result` (a gain positive, a loss negative) and `total` is the result posted, in functional\ncurrency.\n\nIt can run again after a posting dated in the period changed what it remeasured (a payment\nof a revalued invoice or an invoice entered after the run; the close check\n`fx_revaluation` then fails with `fx_changed`): the run again books only the change, at the\nsame closing rate, also auto-reversing; each item then also has `booked` (what the earlier\nentries booked for it). Refused: 409 when the revaluation already ran and nothing changed\n(`fx_revaluation_done`), while its entry waits for approval (`fx_revaluation_pending`) or\nthe period has not started yet (`period_not_started`); 422 for an adjustment period or when\nthe next fiscal year is not opened.",
        "operationId": "run_fx_revaluation_v1_periods__period_id__fx_revaluation_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RunSummary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/leases": {
      "post": {
        "tags": [
          "fixed assets",
          "close"
        ],
        "summary": "Post lease entries for a period",
        "description": "Book the interest and the right-of-use asset's depreciation of every active lease for the\nlease months that ended by the period's end and are not booked yet, in one entry dated at the\nperiod's end through the approval policy: Dr interest / Cr lease liability (lease currency) and\nDr depreciation / Cr accumulated depreciation (functional currency); an operating lease books\nboth to its lease cost account. In the period a lease commences, the part of its first month\nthat ran by the period's end is booked (`stub`). A lease whose change of payments waits for\napproval is skipped (`skipped`). Each lease is booked once per period; running it again books\nonly leases activated since. Refused: 404 for an unknown period; 409 `lease_nothing_due`,\n`lease_change_pending` (nothing else due, and a change of payments waits for approval),\n`period_not_started`, `period_closed`; 422 `lease_regular_period_only`.",
        "operationId": "run_leases_v1_periods__period_id__leases_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LeaseRunSummary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/receivable-allowance": {
      "get": {
        "tags": [
          "close"
        ],
        "summary": "Calculate the allowance for doubtful receivables",
        "description": "What the allowance should be at the period end, invoice by invoice: the open customer\ninvoices (not those of group companies), each with its bucket or doubtful percent, the base\nit is taken on and the allowance; the totals per bucket; and `adjustment`, the difference to\nwhat the allowance account holds, which the run posts. Once run, `run_id` is set and\n`booked` is what the account held before the run. Posts nothing.",
        "operationId": "allowance_proposal_v1_periods__period_id__receivable_allowance_get",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AllowanceProposal"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "close"
        ],
        "summary": "Run the allowance for doubtful receivables",
        "description": "Adjust the allowance account (role `receivable_allowance`) to the allowance the open\ninvoices call for at the period end: one entry dated the period end, Dr allowance expense /\nCr allowance to raise it or the reverse to release part of it, through the approval policy\n(`submit` null when nothing differs). Not reversed: the next period's run adjusts it again.\nRefused: 404 for an unknown period; 409 when the period's run stands (`allowance_done`; a\nrejected one is made again), the period is closed or has not started\n(`period_not_started`); 422 when the chart lacks the accounts (`role_missing`).",
        "operationId": "run_allowance_v1_periods__period_id__receivable_allowance_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AllowanceRunResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/reopen": {
      "post": {
        "tags": [
          "close"
        ],
        "summary": "Reopen a period",
        "description": "Set a closed period back to `open` so entries can be posted to it again. Needs the\napprove scope and a human: the approval policy's `reopen_period` action denies agents.\nThe reason is mandatory and recorded in the audit trail (`period.reopen`). Returns the\nperiod; reopening an open period changes nothing but the audit trail.",
        "operationId": "reopen_period_v1_periods__period_id__reopen_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReopenInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PeriodOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/revenue-recognition": {
      "post": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Run the revenue recognition of a period",
        "description": "Recognise the revenue due by the period end and present the contracts' positions.\n\nPosts at the period end through the approval policy (source `rev`): the recognition entry\n(Dr contract liability, naming the contract / Cr the obligation's revenue account) for every\nschedule line due by the period end, a line from an earlier period marked as a catch-up; then,\nonce that entry is posted, the presentation entry for each contract whose debit position\n(recognised, not yet billed) changed: Dr contract asset, or the unbilled receivable for a\ncontract whose right to consideration is unconditional / Cr contract liability, reversed on the\nfirst day of the next period. The run is incremental: run it again while the period is open\n(after a late satisfaction or invoice) and it posts only what changed; with nothing to post,\n`run_id` is null. A rejected recognition entry releases its lines for the next run. Refused:\n404 for an unknown period; 409 when the period is closed or has not started yet\n(`period_not_started`), or an earlier recognition entry waits for approval; 422 for an\nadjustment period, a missing contract account (roles `contract_liability`, `contract_asset`,\n`unbilled_receivable`), or when the next period is not opened.",
        "operationId": "run_revenue_recognition_v1_periods__period_id__revenue_recognition_post",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecognitionRunOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/periods/{period_id}/revenue-recognition/preview": {
      "get": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Preview the revenue recognition of a period",
        "description": "What `POST /v1/periods/{period_id}/revenue-recognition` would post now; nothing is written.\n\n`recognised` lists, per obligation, the schedule lines due by the period end and not yet\nrecognised; `presentation` the contracts whose debit position the period's entries do not\npresent yet. `notes` says when an earlier recognition entry waits for approval, an earlier\nopen period is to run first or a contract waits for its rate, in English and by code\n(`note_reasons`). Refused: 404 for an unknown period; 422 for an adjustment period.",
        "operationId": "preview_revenue_recognition_v1_periods__period_id__revenue_recognition_preview_get",
        "parameters": [
          {
            "name": "period_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Period Id"
            },
            "description": "Fiscal period id (`GET /v1/entities/{entity}/periods`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecognitionRunOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/plan-versions/{version_id}": {
      "get": {
        "tags": [
          "plans"
        ],
        "summary": "Get a plan version with its lines",
        "description": "A version, its status and totals, and every line by account and period. 404 when it does\nnot exist.",
        "operationId": "get_plan_version_v1_plan_versions__version_id__get",
        "parameters": [
          {
            "name": "version_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`).",
              "examples": [
                "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607"
              ],
              "title": "Version Id"
            },
            "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/plan-versions/{version_id}/approve": {
      "post": {
        "tags": [
          "plans"
        ],
        "summary": "Approve a plan version",
        "description": "Make a submitted version the plan's **current** one: reports compare with it from now on,\nand the version that was current is `superseded` (it stays, with when). **A person's\ndecision**: the policy action `approve_plan` denies agents (403, naming the rule), and by\ndefault whoever prepared the version (created it, set its lines, submitted it) does not\napprove it (403, rule `plan_submitter_does_not_approve`; a one-person organization allows\n`approve_own_plan`). 409 unless it is submitted, when a newer version is current, or\n`version_changed` when its lines are not the submitted ones.",
        "operationId": "approve_plan_version_v1_plan_versions__version_id__approve_post",
        "parameters": [
          {
            "name": "version_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`).",
              "examples": [
                "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607"
              ],
              "title": "Version Id"
            },
            "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`)."
          },
          {
            "name": "lines_digest",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^[0-9a-f]{64}$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The `lines_digest` the approver looked at: when given, the approval is refused (409 `version_changed`) unless the lines are still exactly those.",
              "title": "Lines Digest"
            },
            "description": "The `lines_digest` the approver looked at: when given, the approval is refused (409 `version_changed`) unless the lines are still exactly those."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/plan-versions/{version_id}/comparison": {
      "get": {
        "tags": [
          "plans"
        ],
        "summary": "Compare a plan version with what was posted",
        "description": "Plan against actual for each period of the version (every regular period of a budget's year;\na forecast's periods from its first line to its last): plan, actual, the variance (actual less\nplan), the variance in percent of the plan and whether it is good news, per account or report\nline, with revenue, expenses and net income added up. The actuals are the profit and loss of\nthe posted entries **by period**, closing entries left out and the entries of a year's\nadjustment periods counted in its last regular period; an open period's actuals are not\nfinal (`periods[].status`). Every row ends with the **outlook** of each fiscal year: the actuals\nof its closed periods plus the plan of the others. With `against_version`, the variance is\nagainst that version instead (forecast against budget). Computed when asked; nothing is\nstored. Read-only. 422 when `against_version` is this version or another entity's.",
        "operationId": "compare_plan_version_v1_plan_versions__version_id__comparison_get",
        "parameters": [
          {
            "name": "version_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`).",
              "examples": [
                "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607"
              ],
              "title": "Version Id"
            },
            "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`)."
          },
          {
            "name": "by",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "account",
                "report_line"
              ],
              "type": "string",
              "description": "Rows by `account` or by `report_line` of the profit and loss.",
              "default": "account",
              "title": "By"
            },
            "description": "Rows by `account` or by `report_line` of the profit and loss."
          },
          {
            "name": "against_version",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Also compare with another version of a plan of the same entity: a budget's current version (`current_version_id` of `GET /v1/plans/{plan_id}`) or an earlier forecast. Each cell then carries its amount (`against`) and the variance is this version's less that one's.",
              "title": "Against Version"
            },
            "description": "Also compare with another version of a plan of the same entity: a budget's current version (`current_version_id` of `GET /v1/plans/{plan_id}`) or an earlier forecast. Each cell then carries its amount (`against`) and the variance is this version's less that one's."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Comparison"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/plan-versions/{version_id}/lines": {
      "put": {
        "tags": [
          "plans"
        ],
        "summary": "Set the lines of a draft plan version",
        "description": "Replace every line of a **draft**: one amount per revenue or expense account and regular\nperiod (`YYYY-NN`) of the plan's entity, of the budget's year for a budget, in the functional\ncurrency and the account's natural direction. Repeating the request sets the same lines. 409\nunless the version is a draft; 422 for an unknown or balance sheet account, an unknown or\nadjustment period, a period outside a budget's year, a repeated account and period, or more\ndecimals than the currency has.",
        "operationId": "set_plan_lines_v1_plan_versions__version_id__lines_put",
        "parameters": [
          {
            "name": "version_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`).",
              "examples": [
                "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607"
              ],
              "title": "Version Id"
            },
            "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LinesInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/plan-versions/{version_id}/send-back": {
      "post": {
        "tags": [
          "plans"
        ],
        "summary": "Send a submitted plan version back to draft",
        "description": "Return a submitted version to draft, with the reason kept in the audit trail, so its lines\ncan change. 409 unless it is submitted.",
        "operationId": "send_back_plan_version_v1_plan_versions__version_id__send_back_post",
        "parameters": [
          {
            "name": "version_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`).",
              "examples": [
                "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607"
              ],
              "title": "Version Id"
            },
            "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendBackInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/plan-versions/{version_id}/submit": {
      "post": {
        "tags": [
          "plans"
        ],
        "summary": "Submit a plan version for approval",
        "description": "Fix a draft's lines for approval: they are digested (`lines_digest`) and change only after\nthe version is sent back. Open to anyone who may draft, an agent too; approving is a person's\ndecision. 409 unless it is a draft, 422 when it has no lines.",
        "operationId": "submit_plan_version_v1_plan_versions__version_id__submit_post",
        "parameters": [
          {
            "name": "version_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`).",
              "examples": [
                "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607"
              ],
              "title": "Version Id"
            },
            "description": "Id of the plan version (`GET /v1/plans/{plan_id}`, `version_list`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/plans": {
      "get": {
        "tags": [
          "plans"
        ],
        "summary": "List plans",
        "description": "Budgets and forecasts, the newest first, each with its current (approved) version and how\nmany versions it has. Read-only.",
        "operationId": "list_plans_v1_plans_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's plans (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's plans (code or id)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "budget",
                    "forecast"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only `budget` or `forecast`.",
              "title": "Kind"
            },
            "description": "Only `budget` or `forecast`."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many plans, the newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many plans, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PlanOut"
                  },
                  "title": "Response List Plans V1 Plans Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "plans"
        ],
        "summary": "Create a plan",
        "description": "Create a **budget** (one fiscal year, whose periods must exist) or a **forecast** (a horizon\nof 3 to 24 periods, 12 by default) for an entity, with an empty draft as version 1. A plan is\nnever posted to the ledger: it is read next to it (`GET /v1/plan-versions/{version_id}/\ncomparison`). 409 when the entity already has a plan of that name. Needs an\n`Idempotency-Key`.",
        "operationId": "create_plan_v1_plans_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/plans/{plan_id}": {
      "get": {
        "tags": [
          "plans"
        ],
        "summary": "Get a plan",
        "description": "A plan and all its versions, the newest first (without their lines:\n`GET /v1/plan-versions/{version_id}`). 404 when it does not exist.",
        "operationId": "get_plan_v1_plans__plan_id__get",
        "parameters": [
          {
            "name": "plan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan (`GET /v1/plans`).",
              "examples": [
                "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6"
              ],
              "title": "Plan Id"
            },
            "description": "Id of the plan (`GET /v1/plans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "plans"
        ],
        "summary": "Rename a plan",
        "description": "Change a plan's name (the only thing about a plan that changes; its kind, year and horizon\nare fixed). 409 when the entity has another plan of that name.",
        "operationId": "rename_plan_v1_plans__plan_id__patch",
        "parameters": [
          {
            "name": "plan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan (`GET /v1/plans`).",
              "examples": [
                "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6"
              ],
              "title": "Plan Id"
            },
            "description": "Id of the plan (`GET /v1/plans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlanRename"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlanOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/plans/{plan_id}/roll": {
      "post": {
        "tags": [
          "plans"
        ],
        "summary": "Roll a forecast forward from actuals",
        "description": "A new **draft** of a forecast, rolled from its current version (else its latest): the closed\nperiods of the fiscal year it is in become **actuals** (read from the ledger now and kept as\nlines with method `actual`), the open periods the version planned are carried over, and the\nperiods new to the horizon (the plan's `horizon` periods from the first open one) are filled\nby `run_rate` or `prior_year`, per account by the method of its latest line where that is one\nof them. Periods of the horizon that have no fiscal period yet are reported\n(`horizon_short_by`), not invented. The draft is reviewed, submitted and approved like any\nversion; open to anyone who may draft, an agent too. 409 for a budget; 422 when every period\nis closed. Needs an `Idempotency-Key`.",
        "operationId": "roll_plan_v1_plans__plan_id__roll_post",
        "parameters": [
          {
            "name": "plan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan (`GET /v1/plans`).",
              "examples": [
                "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6"
              ],
              "title": "Plan Id"
            },
            "description": "Id of the plan (`GET /v1/plans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RollInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RollResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/plans/{plan_id}/versions": {
      "post": {
        "tags": [
          "plans"
        ],
        "summary": "Start a new version of a plan",
        "description": "A new **draft** of the plan with the next number: empty, or a copy of the lines of one of\nits versions (`copy_from`), which is how an approved budget is revised. Versions are never\ndeleted, so every figure that was ever current stays on record. Needs an\n`Idempotency-Key`.",
        "operationId": "create_plan_version_v1_plans__plan_id__versions_post",
        "parameters": [
          {
            "name": "plan_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the plan (`GET /v1/plans`).",
              "examples": [
                "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6"
              ],
              "title": "Plan Id"
            },
            "description": "Id of the plan (`GET /v1/plans`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VersionInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VersionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/platform/audit": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "List the operator's audit record",
        "description": "What the operator did and who tried, newest first: sign-ins (and refused ones), sign-outs,\nprovisioning, suspension, reactivation, marking a demo (and refusals), inviting an\nadministrator, opening an organization, and purging a demo. Each row names who (an operator's\naddress or a platform key), from which client address, which organization and the outcome.\nThe record is append-only. 404 for an unknown `before`. Needs the `platform:read` scope.",
        "operationId": "list_audit_v1_platform_audit_get",
        "parameters": [
          {
            "name": "org_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the record of this organization; omit for everything.",
              "title": "Org Id"
            },
            "description": "Only the record of this organization; omit for everything."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "Most rows returned, 1 to 500.",
              "default": 100,
              "title": "Limit"
            },
            "description": "Most rows returned, 1 to 500."
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Continue after this row (its id, the last of the previous page); omit for the newest.",
              "title": "Before"
            },
            "description": "Continue after this row (its id, the last of the previous page); omit for the newest."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PlatformAuditOut"
                  },
                  "title": "Response List Audit V1 Platform Audit Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      }
    },
    "/v1/platform/auth/google": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Sign in to the operator portal with Google",
        "description": "Exchange a Google ID token for an operator session cookie. For the operator portal\n(`/admin`), not for scripts: a script uses a platform key.\n\nThe token is verified as the web UI's is (signature, audience, expiry, verified email), and\nthe account must also belong to its own Google Workspace (the `hd` claim is the address's\ndomain), be of an allowed domain when the deployment limits them, and be on the list of\nplatform operators (`ERP_PLATFORM_OPERATORS`). On success the cookie `erp_platform_session` is\nset (HttpOnly, SameSite=Strict, path `/v1/platform`; Secure on https and in the cloud): it\nlasts 8 hours and ends after 30 idle minutes, and it authenticates `/v1/platform` and nothing\nelse. Every attempt, successful or refused, is recorded in the platform audit. Needs the\n`X-ERP-UI: 1` header (403 `csrf` without it). Refused with 403 for a token that does not\nverify or an account that is not an operator; 422 when Google sign-in is not configured.",
        "operationId": "operator_google_login_v1_platform_auth_google_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OperatorGoogleLogin"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OperatorSignedIn"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/platform/auth/logout": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Sign out of the operator portal",
        "description": "End the operator session whose cookie accompanies the request (it is revoked, not only\nforgotten) and clear the cookie; recorded in the platform audit. With a platform key there is\nno session and nothing happens. The response has no body. Needs `platform:read` and, for a\nsession, the `X-ERP-UI: 1` header.",
        "operationId": "operator_logout_v1_platform_auth_logout_post",
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/charts": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "List chart templates",
        "description": "The chart-of-accounts templates a new entity can start from, the value of `chart` in\n`POST /v1/platform/organizations`. With `country`, the country's standard chart is marked\n`standard`: the one an entity of that country gets when the request names no chart (the\nSwiss KMU chart for CH and LI, the German HGB chart for DE, the French, Italian and Spanish\nnational charts for FR, IT and ES, the generic IFRS chart for a country without one of its\nown). Needs\nthe `platform:read` scope.",
        "operationId": "list_charts_v1_platform_charts_get",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^[A-Z]{2}$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "ISO country code: marks the chart an entity of that country starts from (`standard`).",
              "examples": [
                "CH"
              ],
              "title": "Country"
            },
            "description": "ISO country code: marks the chart an entity of that country starts from (`standard`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ChartTemplate"
                  },
                  "title": "Response List Charts V1 Platform Charts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      }
    },
    "/v1/platform/health": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "Service health: SLOs, error budget, latency, uptime and deploy",
        "description": "How the two services are doing against their objectives, for the operator's console. Per\nservice (`erp-api`, `datavnext-api`): each service level objective with its internal target,\nits compliance over the rolling 28 days and the share of its **error budget** still unspent\n(availability: requests that are not a 5xx, among the requests of real callers; latency: the\nshare of reads or writes the application answered under a threshold; the objectives and\nthresholds are defined in Terraform and named in each entry), the 95th percentile of the last\n24 hours by request class (`read`, `report`, `write`, `heavy`), and the version, revision and\ntime of the last deploy. Also the synthetic uptime checks (probes from outside, every five\nminutes).\n\nThe figures come from Cloud Monitoring and Cloud Run, read with the service's own identity,\nand are cached for 60 seconds. A part that cannot be read is named in `problems` and the rest\nis still answered (`status` is then `degraded`; `unavailable` when nothing could be read,\nwhich is also the answer where monitoring is not configured). Counts and durations of\nrequests only: no organization, person or amount. Needs the `platform:read` scope.",
        "operationId": "service_health_v1_platform_health_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ServiceHealth"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      }
    },
    "/v1/platform/me": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "Who the platform credential is",
        "description": "The operator behind the request: `operator:<address>` for a session of the operator\nportal (with the address as `email`), `platform:<prefix>` for a platform key. The portal asks\nit to learn whether the session is still valid; it ends after `session_hours` from sign-in\nand after `idle_minutes` without a request. `workspace_domains` are the deployment's own\nGoogle Workspace domains, whose people sign in with Google: the portal warns when a customer's\nadministrator is invited on one. Needs the `platform:read` scope.",
        "operationId": "whoami_v1_platform_me_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OperatorMe"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      }
    },
    "/v1/platform/models": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "Show the models behind the built-in agents",
        "description": "The models the built-in agents (bill capture, reconciliation, close review, Q&A) ask, in\norder: the first answers unless it fails or does not answer within two minutes, then the next\n(a refusal is an answer: no other model is asked). `source` says whether they are the\noperator's latest choice or the deployment's defaults. `available` lists the Gemini models\nVertex AI offers at the region now, so that a newer one can be chosen without a deploy (the\nlist is cached for ten minutes; Claude models are not listed by Google). `history` is the\nlatest choices. Needs the `platform:read` scope.",
        "operationId": "get_models_v1_platform_models_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelSettings"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      },
      "put": {
        "tags": [
          "platform"
        ],
        "summary": "Choose the models behind the built-in agents",
        "description": "Choose the models the built-in agents ask, in order (1 to 4 Vertex AI model ids of the\nGemini or Claude family, each once). They are used from the next agent run on, for every\norganization, and replace the deployment's defaults; a Claude model must be enabled in\nModel Garden first. Check a model with `POST /v1/platform/models/check` before choosing it.\nA choice is never changed or deleted: a new one replaces it, and each is recorded in the\nplatform audit (`platform.choose_models`, with the previous models). Only an operator signed\nin to the portal may: a platform key is refused with 403 (and recorded). 422 for an id that\nis not a Gemini or Claude model id, or one named twice. Needs the `platform:provision`\nscope.",
        "operationId": "choose_models_v1_platform_models_put",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ModelChoiceInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelChoiceOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/models/check": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Check that a model answers",
        "description": "Ask one model, without fallback, a short test question at the configured Vertex AI\nregion, and say whether it answered and how long it took. No organization's data is sent. The\ncheck is recorded in the platform audit (`platform.check_model`, outcome `ok` or `failed`).\nA model that is unknown, not enabled or not served at the region answers `ok: false` with\nthe provider's error. 503 when no Google Cloud project is configured. Needs the\n`platform:provision` scope.",
        "operationId": "check_model_v1_platform_models_check_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ModelCheckInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelCheck"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/organizations": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "List organizations",
        "description": "The organizations on the platform, oldest first, with their lifecycle state (`active`\nor `suspended`), their `kind` (`customer` or `demo`), when and by whom each was created and\nwhy it was last suspended or reactivated. With `usage=true` each also has the number of\nentities, people, journal entries and documents and when it was last used (that read is\nrecorded in the platform audit as `org.list_usage`). Never any accounting data beyond counts.\nPages of `limit`: pass the last `org_id` as `after` for the next one. Needs the\n`platform:read` scope.",
        "operationId": "list_organizations_v1_platform_organizations_get",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "suspended"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only `active` or only `suspended` organizations; omit for all.",
              "title": "Status"
            },
            "description": "Only `active` or only `suspended` organizations; omit for all."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "customer",
                    "demo"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only `customer` or only `demo` organizations; omit for all.",
              "title": "Kind"
            },
            "description": "Only `customer` or only `demo` organizations; omit for all."
          },
          {
            "name": "usage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Add each organization's counts and last activity (`usage`). Each one is read in a transaction of its own, so ask for it with a page that you need.",
              "default": false,
              "title": "Usage"
            },
            "description": "Add each organization's counts and last activity (`usage`). Each one is read in a transaction of its own, so ask for it with a page that you need."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 500,
              "minimum": 1,
              "description": "Most organizations returned, 1 to 500.",
              "default": 100,
              "title": "Limit"
            },
            "description": "Most organizations returned, 1 to 500."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Continue after this organization (its id, the last of the previous page); omit for the first page.",
              "title": "After"
            },
            "description": "Continue after this organization (its id, the last of the previous page); omit for the first page."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/OrganizationSummary"
                  },
                  "title": "Response List Organizations V1 Platform Organizations Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      },
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Provision an organization",
        "description": "Create an organization with its entities and invite its first people, in one step.\n\nEach entity starts from a template (`ch_sme`, `de_sme` or `generic`: country, functional\ncurrency, chart of accounts, VAT method, fiscal calendar), which the request can override.\nThe chart brings every account of the roles the services need. The first administrator\n(`admin`) and any `users` are invited by email. When password sign-in is configured, Google\ne-mails each of them the link that sets their password (`password_email_sent`), except to an\naddress of the deployment's Google Workspace domains, whose people sign in with Google. The\ne-mails go out last, once everything is written; if Google refuses (502), nothing is created\nand the request can be repeated. No key is created; the administrator creates their own\nAPI key after the first sign-in, and it is bound to them.\n\nAll or nothing: if anything fails (an unknown chart, an entity code twice, an address\ninvited twice) nothing is created. A retry with the same `Idempotency-Key` and body returns\nthe stored response; the same key with another body answers 409. Needs the\n`platform:provision` scope. The creation is an audit event of the new organization\n(`org.create`, `entity.create`, `user.invite`, by `platform:<prefix>` or, from the operator\nportal, `operator:<address>`), a security event (`platform.organization.provision`) and a row\nof the platform audit. `replayed` is true when the answer is the stored one of an earlier\nrequest with the same key. Refused: 401 without a valid platform key or operator session, 403\nwithout the scope, 409 for a reused key or an entity code or address twice, 422 for an\nunknown chart or a template without country or currency.",
        "operationId": "provision_organization_v1_platform_organizations_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200,
              "description": "Required: a unique key for this provisioning.",
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProvisionInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Provisioned"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "required"
      }
    },
    "/v1/platform/organizations/{org_id}": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "Get an organization",
        "description": "One organization as the operator sees it: its lifecycle state and kind, its entities\n(code, name, country, currency), its people (address, role, status, last sign-in), its counts\nand the evidence of use that decides whether it may be marked as a demo. Master data and\ncounts only: no ledger line, amount or document. Opening an organization is recorded in the\nplatform audit (`org.view`). 404 for an unknown id. Needs the `platform:read` scope.",
        "operationId": "get_organization_v1_platform_organizations__org_id__get",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrganizationDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      }
    },
    "/v1/platform/organizations/{org_id}/admins": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Invite or show again an organization's first administrator",
        "description": "Invite an administrator of an existing organization, who signs in with the Google account\nof the address or, without one, with a password. A person who is not a user yet is added\n(`invited`); one who was invited and has not signed in is left as they are\n(`already_invited`) and the answer says again where to sign in. When password sign-in is\nconfigured, Google e-mails them the link that sets their password, a fresh one each time\n(`password_email_sent`; not to an address of the deployment's Google Workspace domains;\n502 when Google refuses). Both are recorded in the platform\naudit; a new invitation is also an event of the organization's audit trail. Safe to repeat.\n409 for a person who has signed in, who is disabled or who was invited with another role;\n404 for an unknown organization. Needs the `platform:provision` scope.",
        "operationId": "invite_admin_v1_platform_organizations__org_id__admins_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdminInvite"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdminInvited"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/organizations/{org_id}/delete": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Delete an organization",
        "description": "Delete an organization and its test copies, with everything they hold (ADR-0042). Only an\noperator signed in to the portal may: a platform key is refused with 403. `confirm_name` must\nbe the organization's exact name (422 otherwise). An organization that shows signs of real use\n(the evidence of its detail) is refused with 409 `customer_activity` unless `accept_activity`\nis true. The answer is `202`: from now on nobody reaches the organization. For an hour\n(until `delete_after`) the deletion can be undone (`undo-delete`); after that the owner's job,\nwhich runs every hour and at every deploy, deletes it with the demo purge over the owner\nconnection (ADR-0022) and records how many rows it deleted, and nothing brings its books back\nbut a restore of the database. Asking again changes nothing. The request and a refusal are\nrecorded in the platform audit. 404 for an unknown id. Needs the `platform:provision` scope.",
        "operationId": "delete_organization_v1_platform_organizations__org_id__delete_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DeleteOrganizationInput"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteOrganizationResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/organizations/{org_id}/exports": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "List an organization's exports",
        "description": "The organization's exports, newest first, with their status, whoever asked for them.\nPages of `limit`: pass the last `id` as `after` for the next one. Needs the `platform:read`\nscope. 404 for an unknown organization.",
        "operationId": "list_organization_exports_v1_platform_organizations__org_id__exports_get",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1,
              "description": "Most exports returned, 1 to 100.",
              "default": 25,
              "title": "Limit"
            },
            "description": "Most exports returned, 1 to 100."
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Continue after this export (its id, the last of the previous page); omit for the first page.",
              "title": "After"
            },
            "description": "Continue after this export (its id, the last of the previous page); omit for the first page."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExportOut"
                  },
                  "title": "Response List Organization Exports V1 Platform Organizations  Org Id  Exports Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      },
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Export an organization's data",
        "description": "Ask for the complete package of an organization's data, as the organization's own\nadministrators can (`POST /v1/exports`): every table as CSV and JSON, the reports as PDF and\nCSV, every stored file checked against its SHA-256, the hash-chain verification, a manifest\nwith the hash of every file, the README, and for a German entity the `index.xml`. Meant for\noffboarding: suspend the organization first (`POST .../suspend`), then export, then hand\nover. The export runs asynchronously from one consistent snapshot; follow it with\n`GET .../exports/{id}`.\n\nThe platform reads none of the books through this API: the job that builds the package does,\nover the database's row-level security, scoped to the one organization. When it has\nsucceeded, the SHA-256 of the package is recorded in the platform's append-only audit record\n(`platform_audit`, action `org.export`), so that we can later attest what was handed over.\nOne export at a time per organization (`409 export_in_progress`). Needs the\n`platform:provision` scope. Starting is an audit event of the organization (`export.start`,\nby `platform:<prefix>`), a security event (`platform.export.start`) and a row of the\noperator's record (`org.export_start`). 404 for an unknown\norganization. A retry with the same `Idempotency-Key` returns the first answer.",
        "operationId": "start_organization_export_v1_platform_organizations__org_id__exports_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 200,
              "description": "Required: a unique key for this export request.",
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "required"
      }
    },
    "/v1/platform/organizations/{org_id}/exports/{run_id}": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "Get an organization's export",
        "description": "One export with its status and, once it has succeeded, the file's SHA-256 and the\nhand-over statement. 404 for an unknown organization or an export of another one. Needs the\n`platform:read` scope.",
        "operationId": "get_organization_export_v1_platform_organizations__org_id__exports__run_id__get",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          },
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of an export (`GET /v1/exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Run Id"
            },
            "description": "Id of an export (`GET /v1/exports`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:read"
            ]
          }
        ],
        "x-required-scope": "platform:read"
      }
    },
    "/v1/platform/organizations/{org_id}/exports/{run_id}/download": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "Download an organization's export",
        "description": "The package of a succeeded export, as a ZIP, streamed through the API (use a client that\nwrites to a file; for a large package prefer the link). Every download is an audit event of\nthe organization (`export.download`), a security event (`platform.export.download`) and a row\nof the operator's record (`org.export_download`).\nNeeds the `platform:provision` scope. 409 `export_not_ready` unless the export succeeded and\nhas not expired.",
        "operationId": "download_organization_export_v1_platform_organizations__org_id__exports__run_id__download_get",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          },
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of an export (`GET /v1/exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Run Id"
            },
            "description": "Id of an export (`GET /v1/exports`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The package: a ZIP, streamed (SHA-256 in `X-Content-SHA256`).",
            "content": {
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision"
      }
    },
    "/v1/platform/organizations/{org_id}/exports/{run_id}/link": {
      "get": {
        "tags": [
          "platform"
        ],
        "summary": "Get a link to download an organization's export",
        "description": "A signed link that downloads the package straight from the store without credentials,\nfor seven days at most and never beyond the package's expiry: this is how the package is\nhanded over to the customer, who has no platform key. Anyone who holds the link can download\nuntil it ends: send it over a channel you trust, together with the statement\n(`GET .../exports/{id}`: SHA-256 of the file). Giving the link is an audit event\n(`export.link`), a security event (`platform.export.download`) and a row of the operator's\nrecord (`org.export_link`). Needs the\n`platform:provision` scope. 409 `export_not_ready` unless the export succeeded and has not\nexpired, 409 `no_signed_link` where links cannot be signed (use `/download`).",
        "operationId": "organization_export_link_v1_platform_organizations__org_id__exports__run_id__link_get",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          },
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of an export (`GET /v1/exports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Run Id"
            },
            "description": "Id of an export (`GET /v1/exports`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExportLink"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision"
      }
    },
    "/v1/platform/organizations/{org_id}/mark-demo": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Mark an organization as a demo",
        "description": "Make an organization a demo: the one kind the operator may purge (with a command, never\nthrough this API; a customer's books are never deleted). Only an operator signed in to the\nportal may: a platform key is refused with 403. `confirm_name` must be the organization's exact\nname (422 otherwise). It is done by a database function that also checks the evidence of\nuse: an organization that shows any sign of real use (an invoice sent to a customer, a file\narchived as issued, a person who is not an administrator or was invited by a person or a key,\nmore than one person who has signed in, entries or documents not created by the demo seed) is\nrefused with 409 `customer_activity`, and the evidence is in the answer. There is no way to\naccept it here: an organization that was used is marked only by the command `erp platform\nmark-demo --accept-activity` on the owner connection. A marking and a refusal are recorded in\nthe platform audit. Marking a demo again changes and records nothing. 404 for an unknown id.\nNeeds the `platform:provision` scope.",
        "operationId": "mark_demo_v1_platform_organizations__org_id__mark_demo_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarkDemoInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarkDemoResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/organizations/{org_id}/passkey-reset": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Reset a person's passkeys",
        "description": "For a person of the organization who lost every device with a passkey and has no\nadministrator to ask, such as a company's only owner: remove their passkeys and end all\ntheir sessions, in every organization; their next sign-in creates a new first passkey.\nOnly an operator signed in to the portal (403 for a platform key), with the\n`platform:provision` scope. 404 when the address is not a user of the organization.\nRecorded in the platform audit (`org.passkey_reset`), the organization's audit trail\n(`user.passkey_reset`) and as a security event (`passkey.reset`).",
        "operationId": "operator_reset_passkeys_v1_platform_organizations__org_id__passkey_reset_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OperatorPasskeyReset"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OperatorPasskeyResetDone"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/organizations/{org_id}/reactivate": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Reactivate an organization",
        "description": "Lift a suspension: the organization can change data again. The `reason` goes to the\naudit trail (`org.reactivate`) and to a security event. Safe to repeat: an organization\nthat is already active is returned unchanged. 404 for an unknown id. Needs the\n`platform:provision` scope.",
        "operationId": "reactivate_organization_v1_platform_organizations__org_id__reactivate_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatusChange"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/organizations/{org_id}/suspend": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Suspend an organization",
        "description": "Make an organization read-only. From now on its API keys and sessions can read\neverything and change nothing: every request that would change state answers 403\n(`suspended`); signing in and out still work. Nothing is deleted. The `reason` goes to\nthe organization's audit trail (`org.suspend`) and to a security event. Safe to repeat: an\norganization that is already suspended is returned unchanged. 404 for an unknown id.\nNeeds the `platform:provision` scope.",
        "operationId": "suspend_organization_v1_platform_organizations__org_id__suspend_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatusChange"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/platform/organizations/{org_id}/undo-delete": {
      "post": {
        "tags": [
          "platform"
        ],
        "summary": "Undo the deletion of an organization",
        "description": "Undo a deletion asked for less than an hour ago (before `delete_after`): the\norganization, and the test copies deleted with it, are reachable again as they were. Only an\noperator signed in to the portal may: a platform key is refused with 403. After the hour the\nowner's job may be deleting it: 409. Safe to repeat: an organization whose deletion was not\nasked for is returned unchanged. Recorded in the platform audit (`org.delete_undone`). 404 for\nan unknown id. Needs the `platform:provision` scope.",
        "operationId": "undo_delete_organization_v1_platform_organizations__org_id__undo_delete_post",
        "parameters": [
          {
            "name": "org_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Organization id (`GET /v1/platform/organizations`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Org Id"
            },
            "description": "Organization id (`GET /v1/platform/organizations`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TenantOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "platformAuth": [
              "platform:provision"
            ]
          }
        ],
        "x-required-scope": "platform:provision",
        "x-idempotency": "none"
      }
    },
    "/v1/price-lists": {
      "get": {
        "tags": [
          "price lists"
        ],
        "summary": "List price lists",
        "description": "The entities' price lists by code, each with every price (by product, tier and the newest\nfirst) and the customers that take it. Read-only.",
        "operationId": "list_price_lists_v1_price_lists_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's lists (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's lists (code or id)."
          },
          {
            "name": "active",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`true`: only those in use; `false`: only inactive ones.",
              "title": "Active"
            },
            "description": "`true`: only those in use; `false`: only inactive ones."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, by code.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many, by code."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PriceListOut"
                  },
                  "title": "Response List Price Lists V1 Price Lists Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "price lists"
        ],
        "summary": "Create a price list",
        "description": "A price list of an entity in one currency, optionally with its first prices (each of a\nproduct of the entity, for a quantity from a minimum on, from a day). 409 when the entity has\na list with the code; 404 for an unknown product; 422 for a price without the period its\nproduct's kind needs. Nothing is posted. Needs an `Idempotency-Key`.",
        "operationId": "create_price_list_v1_price_lists_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceListInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceListOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/price-lists/{price_list_id}": {
      "get": {
        "tags": [
          "price lists"
        ],
        "summary": "Get a price list",
        "description": "One price list with every price and its customers. 404 when it does not exist.",
        "operationId": "get_price_list_v1_price_lists__price_list_id__get",
        "parameters": [
          {
            "name": "price_list_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the price list (`GET /v1/price-lists`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Price List Id"
            },
            "description": "Id of the price list (`GET /v1/price-lists`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceListOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "price lists"
        ],
        "summary": "Change a price list",
        "description": "Rename it, or `active: false` to stop lines proposing its prices (it is never deleted;\nits customers keep it, unused, until it is active again or they are given another). Its\nentity, code and currency never change. Audited with the previous values.",
        "operationId": "update_price_list_v1_price_lists__price_list_id__patch",
        "parameters": [
          {
            "name": "price_list_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the price list (`GET /v1/price-lists`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Price List Id"
            },
            "description": "Id of the price list (`GET /v1/price-lists`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceListUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceListOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/price-lists/{price_list_id}/prices": {
      "post": {
        "tags": [
          "price lists"
        ],
        "summary": "Record a price on a price list",
        "description": "A price of a product on the list for a line of at least `min_quantity` (default 1), from\na day (default today where the entity is). A price is never changed: a new one is recorded\nfrom a later day. The price in force for a quantity on a day is the highest tier at or below\nthe quantity, that tier's latest from on or before the day. 409 when the list has a price of\nthe product for the tier from that day. Needs an `Idempotency-Key`.",
        "operationId": "add_price_list_price_v1_price_lists__price_list_id__prices_post",
        "parameters": [
          {
            "name": "price_list_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the price list (`GET /v1/price-lists`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Price List Id"
            },
            "description": "Id of the price list (`GET /v1/price-lists`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceListPriceInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceListPriceOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/products": {
      "get": {
        "tags": [
          "products"
        ],
        "summary": "List products",
        "description": "What the entities sell, by code, each with its list prices and standalone selling prices.\nRead-only.",
        "operationId": "list_products_v1_products_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's products (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's products (code or id)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "one_off",
                    "recurring"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this kind.",
              "title": "Kind"
            },
            "description": "Only this kind."
          },
          {
            "name": "active",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`true`: only those sold; `false`: only inactive ones.",
              "title": "Active"
            },
            "description": "`true`: only those sold; `false`: only inactive ones."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, by code.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many, by code."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProductOut"
                  },
                  "title": "Response List Products V1 Products Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "products"
        ],
        "summary": "Create a product",
        "description": "A product of an entity, with the revenue account (a revenue account of the entity; default\nthe entity's default revenue account), supply type and VAT rate type its invoice lines take,\nand optionally its first list prices. 409 when the entity has a product with the code; 422\nfor an account that is not a revenue account or a price without the period its kind needs.\nNothing is posted. Needs an `Idempotency-Key`.",
        "operationId": "create_product_v1_products_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/products/{product_id}": {
      "get": {
        "tags": [
          "products"
        ],
        "summary": "Get a product",
        "description": "One product with every list price and standalone selling price. 404 when it does not\nexist.",
        "operationId": "get_product_v1_products__product_id__get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the product (`GET /v1/products`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Product Id"
            },
            "description": "Id of the product (`GET /v1/products`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "products"
        ],
        "summary": "Change a product",
        "description": "Change what the body names; `active: false` stops new invoice lines from naming it (a credit\nnote still credits it). Its entity, code and kind never change, and lines already written keep\nwhat they took from it. The change is audited with the previous values.",
        "operationId": "update_product_v1_products__product_id__patch",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the product (`GET /v1/products`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Product Id"
            },
            "description": "Id of the product (`GET /v1/products`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProductUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProductOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/products/{product_id}/price": {
      "get": {
        "tags": [
          "products"
        ],
        "summary": "Get the price in force",
        "description": "The list price and the standalone selling price in force on a day: what an invoice line of\nthe product proposes. With `party`, also the customer's price (`customer_price`), from the\nactive price list the customer takes in the currency, for the `quantity`: a line proposes it\nbefore the list price. 404 for an unknown customer. Read-only.",
        "operationId": "get_price_in_force_v1_products__product_id__price_get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the product (`GET /v1/products`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Product Id"
            },
            "description": "Id of the product (`GET /v1/products`)."
          },
          {
            "name": "currency",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Z]{3}$",
              "description": "Currency.",
              "examples": [
                "CHF"
              ],
              "title": "Currency"
            },
            "description": "Currency."
          },
          {
            "name": "on",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day; default today.",
              "title": "On"
            },
            "description": "The day; default today."
          },
          {
            "name": "party",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "A customer of the product's entity (code or id): the answer then also carries the customer's price from its price list in the currency, if any.",
              "examples": [
                "C-CH"
              ],
              "title": "Party"
            },
            "description": "A customer of the product's entity (code or id): the answer then also carries the customer's price from its price list in the currency, if any."
          },
          {
            "name": "quantity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "number",
                  "exclusiveMinimum": 0.0
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The quantity of the line, which picks the volume tier of the customer's price; default 1.",
              "examples": [
                "10"
              ],
              "title": "Quantity"
            },
            "description": "The quantity of the line, which picks the volume tier of the customer's price; default 1."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceInForce"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/products/{product_id}/prices": {
      "post": {
        "tags": [
          "products"
        ],
        "summary": "Record a list price",
        "description": "A list price in a currency from a day (default today). A price is never changed: a new price\nis a new one from a later day, and the one in force on a day is the latest from on or before\nit. 409 when the product has a price in the currency from that day. Needs an\n`Idempotency-Key`.",
        "operationId": "add_product_price_v1_products__product_id__prices_post",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the product (`GET /v1/products`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Product Id"
            },
            "description": "Id of the product (`GET /v1/products`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PriceInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PriceOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/products/{product_id}/sales-tax": {
      "get": {
        "tags": [
          "sales tax"
        ],
        "summary": "Get a product's sales tax category",
        "description": "The product's category; `general` when none was set.",
        "operationId": "get_product_v1_products__product_id__sales_tax_get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the product (`GET /v1/products`).",
              "title": "Product Id"
            },
            "description": "Id of the product (`GET /v1/products`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxProductOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "sales tax"
        ],
        "summary": "Set a product's sales tax category",
        "description": "The product's category, which decides with the state's rules how much of its price is\ntaxed. Needs the `admin` scope and the policy action `manage_accounts`.",
        "operationId": "put_product_v1_products__product_id__sales_tax_put",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the product (`GET /v1/products`).",
              "title": "Product Id"
            },
            "description": "Id of the product (`GET /v1/products`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxProductInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxProductOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/products/{product_id}/ssps": {
      "post": {
        "tags": [
          "products"
        ],
        "summary": "Record a standalone selling price",
        "description": "The price the product sells for on its own (IFRS 15.77), with how it was established, in a\ncurrency from a day (default today). It allocates the price of a revenue contract to its\nobligations, so a person records it: the policy action `set_ssp`, which agents are always\ndenied (403). Never changed, like a list price (409 for a second one from the same day).\nNeeds an `Idempotency-Key`.",
        "operationId": "add_product_ssp_v1_products__product_id__ssps_post",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the product (`GET /v1/products`).",
              "examples": [
                "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
              ],
              "title": "Product Id"
            },
            "description": "Id of the product (`GET /v1/products`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SspInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SspOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/public/quotes/{token}": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "View Quote Online",
        "description": "The quote as its customer sees it on the link, without a sign-in: the seller, the lines,\nVAT, totals, until when it is valid and whether it can be answered (`state`). 404 for a\nlink that is wrong or turned off.",
        "operationId": "view_quote_online_v1_public_quotes__token__get",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100,
              "description": "The link's token, as in `/app/quote/{token}`.",
              "title": "Token"
            },
            "description": "The link's token, as in `/app/quote/{token}`."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "it",
                    "sv"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`de`, `fr`, `it`, `en` or `sv`.",
              "title": "Language"
            },
            "description": "`de`, `fr`, `it`, `en` or `sv`."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteOnlineView"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ]
      }
    },
    "/v1/public/quotes/{token}/accept": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Accept Quote Online",
        "description": "Accept the quote for your company, naming the version you read (`revision`): kept with\nyour name, the time and your internet address, and the seller's order is made from it. 409\n`quote_not_open_online` when it changed, expired or was answered since.",
        "operationId": "accept_quote_online_v1_public_quotes__token__accept_post",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100,
              "description": "The link's token, as in `/app/quote/{token}`.",
              "title": "Token"
            },
            "description": "The link's token, as in `/app/quote/{token}`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OnlineAcceptInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteOnlineView"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/public/quotes/{token}/decline": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Decline Quote Online",
        "description": "Decline the quote, with why if you like, naming the version you read. 409\n`quote_not_open_online` when it changed, expired or was answered since.",
        "operationId": "decline_quote_online_v1_public_quotes__token__decline_post",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100,
              "description": "The link's token, as in `/app/quote/{token}`.",
              "title": "Token"
            },
            "description": "The link's token, as in `/app/quote/{token}`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OnlineDeclineInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteOnlineView"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "x-idempotency": "none"
      }
    },
    "/v1/public/quotes/{token}/pdf": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "Quote Online Pdf",
        "description": "The PDF of the version the page shows, as it was handed over. 409 while it is being\nchanged.",
        "operationId": "quote_online_pdf_v1_public_quotes__token__pdf_get",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 100,
              "description": "The link's token, as in `/app/quote/{token}`.",
              "title": "Token"
            },
            "description": "The link's token, as in `/app/quote/{token}`."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` sends the file as an attachment.",
              "default": false,
              "title": "Download"
            },
            "description": "`true` sends the file as an attachment."
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ]
      }
    },
    "/v1/purchase-orders/{order}": {
      "get": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Get Purchase Order",
        "description": "A purchase order by id or number: lines with ordered, received and invoiced\nquantities, receipts and the bills matched to it. The ETag names its version.",
        "operationId": "get_purchase_order_v1_purchase_orders__order__get",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Update Purchase Order",
        "description": "Change a draft (``lines`` replaces every line); 409 once submitted, 412 when\n`If-Match` names an older version.",
        "operationId": "update_purchase_order_v1_purchase_orders__order__patch",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed purchase order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed purchase order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OrderUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/purchase-orders/{order}/cancel": {
      "post": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Cancel Purchase Order",
        "description": "Cancel an order on which nothing was received or invoiced (409 otherwise); a\npending approval request is withdrawn. A cancelled order no longer changes.",
        "operationId": "cancel_purchase_order_v1_purchase_orders__order__cancel_post",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed purchase order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed purchase order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CancelInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required",
        "x-if-match": "optional"
      }
    },
    "/v1/purchase-orders/{order}/close": {
      "post": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Close Purchase Order",
        "description": "Close an approved order for the rest (short close) with a reason: what was received\nor invoiced stays, the rest of each line is closed (`closed_quantity`) and the order is\n`closed`. Receipts beyond what is left are refused, and a bill beyond it is a quantity\nvariance that blocks its payment. 409 for a draft, cancelled or already closed order, or\nwhen nothing is left to close; 412 when `If-Match` names an older version.",
        "operationId": "close_purchase_order_v1_purchase_orders__order__close_post",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed purchase order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed purchase order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CloseInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required",
        "x-if-match": "optional"
      }
    },
    "/v1/purchase-orders/{order}/goods-received": {
      "get": {
        "tags": [
          "goods received"
        ],
        "summary": "Received, billed and open GR/IR per order line",
        "description": "Per order line: what was received at receipt value, what bills billed (net of credit\nnotes) and cleared, and what is open on the GR/IR account (received, not billed).",
        "operationId": "order_goods_received_v1_purchase_orders__order__goods_received_get",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderGrniOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/purchase-orders/{order}/grni-write-off": {
      "post": {
        "tags": [
          "goods received"
        ],
        "summary": "Write off goods received that will never be billed",
        "description": "Take what is open on the GR/IR account of the order's lines (goods received free of\ncharge, or billed without the order's number) off GR/IR: one journal entry debits GR/IR and\ncredits the chosen account (default: the line's own account, else that of its bills, else\nfor a stock item the inventory changes account). It is dated from the line's last receipt\nto today. The stock is not touched. People only (policy action `record_receipt`); the entry\npasses the posting approval (limit and four eyes), and while it waits the lines count as\nwritten off. Refusals: `grni_nothing_open`, `grni_line_nothing_open`,\n`grni_write_off_pending`, `grni_write_off_future`, `grni_write_off_before_receipt`,\n`grni_write_off_control_account`, `grni_write_off_account_missing`.",
        "operationId": "write_off_grni_v1_purchase_orders__order__grni_write_off_post",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GrniWriteOffInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GrniWriteOffOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/purchase-orders/{order}/history": {
      "get": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Purchase Order History",
        "description": "The order's audit events: changes, submission, approval, receipts and status\nchanges, oldest first.",
        "operationId": "purchase_order_history_v1_purchase_orders__order__history_get",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AuditEventOut"
                  },
                  "title": "Response Purchase Order History V1 Purchase Orders  Order  History Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/purchase-orders/{order}/receipts": {
      "post": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Receive Purchase Order",
        "description": "Record goods or services received per order line (a negative quantity corrects an\nearlier receipt). A line of a stock item, or any other line that needs a receipt and names\nan account, posts at receipt value against the GR/IR account (see goods received). Bills of\nthe order blocked by a quantity variance are matched again once the receipt is posted, so a\nbill that arrived before the goods is released.",
        "operationId": "receive_purchase_order_v1_purchase_orders__order__receipts_post",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/purchase-orders/{order}/receipts/preview": {
      "post": {
        "tags": [
          "goods received"
        ],
        "summary": "Show what a receipt would post",
        "description": "The value each line of a receipt would post, in the functional currency at the receipt\nday's rate, and the account it debits (inventory, or the order line's account) against the\nGR/IR account. Nothing is recorded.",
        "operationId": "preview_receipt_v1_purchase_orders__order__receipts_preview_post",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReceiptInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReceiptPreviewOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/purchase-orders/{order}/submit": {
      "post": {
        "tags": [
          "purchase-orders"
        ],
        "summary": "Submit Purchase Order",
        "description": "Submit a draft for approval. By default a second person approves it\n(`POST /v1/approvals/{id}/approve`, action `approve_purchase_order`); when the approval\npolicy allows it, a person with the approve scope approves it at once. Agents may\nsubmit, never approve.",
        "operationId": "submit_purchase_order_v1_purchase_orders__order__submit_post",
        "parameters": [
          {
            "name": "order",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`.",
              "examples": [
                "PO-2026-000001"
              ],
              "title": "Order"
            },
            "description": "Purchase order id (uuid) or number, e.g. `PO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed purchase order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed purchase order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OrderCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/record-access": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List what each person sees",
        "description": "Every person of the organization with which sales records they see (`all`, `team` or\n`own`) and the teams they are in, by name.",
        "operationId": "list_record_access_v1_record_access_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PersonAccess"
                  },
                  "title": "Response List Record Access V1 Record Access Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/record-access/hand-over": {
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Hand one person's records to another",
        "description": "Give every customer, contact and deal (open, won and lost) one person owns to another, in\none company or all: when someone leaves or changes territory. Activities stay with who did\nthem; open tasks keep their assignee, and how many are left is returned. For someone who sees\nall records (403 `hand_over_needs_all_records`); 422 `owner_disabled` for a disabled new\nowner. Each record's history shows the change. Needs an `Idempotency-Key`.",
        "operationId": "hand_over_records_v1_record_access_hand_over_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/HandOverInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HandOverOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/recurring-invoices": {
      "get": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "List recurring invoices",
        "description": "Recurring invoice templates, the one that falls due first at the top (templates without a\nnext due date, the ended ones, last). `due_through` is the **due list**: the templates a run\nthrough that day would make invoices for, the same rule as the Role Center cue\n(`recurring_due` in `GET /v1/entities/{entity}/overview`). Read-only.",
        "operationId": "list_recurring_invoices_v1_recurring_invoices_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's templates (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's templates (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "draft",
                    "ended",
                    "paused",
                    "pending_approval"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only templates with this status: `draft`, `pending_approval`, `active`, `paused` or `ended`.",
              "title": "Status"
            },
            "description": "Only templates with this status: `draft`, `pending_approval`, `active`, `paused` or `ended`."
          },
          {
            "name": "party",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's templates (code or id); needs `entity`.",
              "examples": [
                "C-CH"
              ],
              "title": "Party"
            },
            "description": "Only this customer's templates (code or id); needs `entity`."
          },
          {
            "name": "due_through",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the templates a run through this day would make invoices for: active, with a next due date on or before it (ISO 8601). This is the list the Role Center's `recurring_due` counts.",
              "examples": [
                "2026-11-30"
              ],
              "title": "Due Through"
            },
            "description": "Only the templates a run through this day would make invoices for: active, with a next due date on or before it (ISO 8601). This is the list the Role Center's `recurring_due` counts."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many templates to return, the next to fall due first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many templates to return, the next to fall due first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RecurringInvoiceOut"
                  },
                  "title": "Response List Recurring Invoices V1 Recurring Invoices Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "Create a recurring invoice",
        "description": "Create a recurring invoice as a **draft**: the customer, currency, lines, frequency,\nstart and end dates and payment terms of an invoice that repeats. Nothing is invoiced until\na person activates it (`POST .../{template_id}/activate`) and a second person approves its\nterms, and then a run makes the invoices (`POST /v1/recurring-invoices/run`). The first\ninvoice is built without being kept, so a missing account, an unknown customer or a tax\ndecision that cannot be made is refused now (404, 422) instead of at the first run. The\nnext due date is the start date. Needs an `Idempotency-Key`.",
        "operationId": "create_recurring_invoice_v1_recurring_invoices_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringInvoiceInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringInvoiceOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/recurring-invoices/run": {
      "post": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "Make the recurring invoices that are due",
        "description": "Make the invoices of every active recurring invoice that has a due date on or before\n`through` (never after today where the template's company is), in date order, as ordinary\ninvoices dated their due date.\n\nEach is **a draft** for a person to submit, or, when the template has `auto_submit`, is\nsubmitted by the system through the normal path (the approval policy, the open period, the\nnumbering), which the approval of the terms authorised. It is **idempotent**: a repeated,\nretried or simultaneous run makes nothing twice (one invoice per template and due date,\nenforced by the database); an `Idempotency-Key` replays the first answer. A period that cannot\nbe made (a closed period, an inactive customer) is `failed` with its error, stops that template\nat that date and leaves the others running; the next run tries it again. At most twelve due\ndates per template are made in one run: `more_due` says to run again. A person or a script\ncalls this, and the scheduled close job runs it daily for the entities whose close calendar\nnames `recurring_invoices` (`PUT /v1/entities/{entity}/close-schedule`). Needs an\n`Idempotency-Key`.",
        "operationId": "run_recurring_invoices_v1_recurring_invoices_run_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringRunInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringRunResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/recurring-invoices/{template_id}": {
      "get": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "Get a recurring invoice",
        "description": "One recurring invoice: its terms, status, next due date, whether the current terms are the\napproved ones (`terms_approved`), the pending approval request and how many invoices it has\nmade. 404 when it does not exist.",
        "operationId": "get_recurring_invoice_v1_recurring_invoices__template_id__get",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Template Id"
            },
            "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringInvoiceOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "Change a recurring invoice",
        "description": "Change a recurring invoice. Omitted fields keep their value; `lines` replaces every line.\nOnly `name` changes without consequence: any change to the terms **pauses an active template**\n(so it makes no invoice until a second person approves the new terms) and takes one waiting\nfor approval back to draft, withdrawing the request. `frequency` and `start_date` cannot change\nonce an invoice was made (409): end the template and create a new one. 409 for an ended\ntemplate; 404, 422 as when creating.",
        "operationId": "update_recurring_invoice_v1_recurring_invoices__template_id__patch",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Template Id"
            },
            "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringInvoiceUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringInvoiceOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/recurring-invoices/{template_id}/activate": {
      "post": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "Activate a recurring invoice",
        "description": "Ask for the terms of a draft or paused recurring invoice to be approved, so that runs make\nits invoices. **A human decision**: the policy action `activate_recurring_invoice` denies\nagents (403, naming the rule). By default a second person approves\n(`POST /v1/approvals/{approval_id}/approve`; never the person who created the template or\nasked), and the approval is bound to the digest of the terms: it activates only these terms,\nand says on its face whether the invoices are submitted automatically (`auto_submit`). A\npaused template whose terms are the ones already approved runs again at once. An\norganization with one person allows the action in its approval policy. 409 when the customer\nis not active, the template is not a draft or paused, or no due date is left before its end\ndate.",
        "operationId": "activate_recurring_invoice_v1_recurring_invoices__template_id__activate_post",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Template Id"
            },
            "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringActivation"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/recurring-invoices/{template_id}/pause": {
      "post": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "Pause a recurring invoice",
        "description": "Stop an active recurring invoice from making invoices, with a reason kept in the audit\ntrail. It makes none until it is activated again (at once if its terms are unchanged since the\napproval). Pausing is open to anyone who may draft: it makes nothing happen. 409 unless the\ntemplate is active.",
        "operationId": "pause_recurring_invoice_v1_recurring_invoices__template_id__pause_post",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Template Id"
            },
            "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringPause"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringInvoiceOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/recurring-invoices/{template_id}/runs": {
      "get": {
        "tags": [
          "recurring invoices"
        ],
        "summary": "List the invoices a recurring invoice made",
        "description": "Every period a run has made or tried for the template, oldest first: the due date, what came\nof it (`drafted`, `posted`, `pending_approval`, `failed`), the invoice with its number and its\nstatus now, the error of a failed period, and who ran it. 404 when the template does not\nexist.",
        "operationId": "list_recurring_invoice_runs_v1_recurring_invoices__template_id__runs_get",
        "parameters": [
          {
            "name": "template_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Template Id"
            },
            "description": "Id of the recurring invoice (`GET /v1/recurring-invoices`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RecurringRunOut"
                  },
                  "title": "Response List Recurring Invoice Runs V1 Recurring Invoices  Template Id  Runs Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/recurring-journals": {
      "get": {
        "tags": [
          "recurring journals"
        ],
        "summary": "List recurring journals",
        "description": "Recurring journals, the one that falls due first at the top (the ended ones last).\n`due_through` is the **due list**: the recurring journals a run through that day would make\nentries for, the same rule as the Role Center cue. Read-only.",
        "operationId": "list_recurring_journals_v1_recurring_journals_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's recurring journals (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's recurring journals (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "draft",
                    "ended",
                    "paused"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those with this status: `draft`, `active`, `paused` or `ended`.",
              "title": "Status"
            },
            "description": "Only those with this status: `draft`, `active`, `paused` or `ended`."
          },
          {
            "name": "due_through",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those a run through this day would make entries for: active, with a next due date on or before it (ISO 8601). This is the list the Role Center's `recurring_journals_due` counts.",
              "examples": [
                "2026-10-31"
              ],
              "title": "Due Through"
            },
            "description": "Only those a run through this day would make entries for: active, with a next due date on or before it (ISO 8601). This is the list the Role Center's `recurring_journals_due` counts."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many to return, next due first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many to return, next due first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RecurringJournalOut"
                  },
                  "title": "Response List Recurring Journals V1 Recurring Journals Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "recurring journals"
        ],
        "summary": "Create a recurring journal",
        "description": "Create a recurring journal as a **draft**: the description and lines of a journal entry\nthat repeats, how often, from when until when, and whether each entry is reversed on the\nfirst day of the next period (an accrual). Nothing is posted until a person activates it and\na run makes the entries that are due (`POST /v1/recurring-journals/run`). The first entry is\nbuilt without being kept, so a missing account, lines that do not balance or a closed period\nare refused now (404, 409, 422) instead of at the first run. Needs an `Idempotency-Key`.",
        "operationId": "create_recurring_journal_v1_recurring_journals_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringJournalInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringJournalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/recurring-journals/run": {
      "post": {
        "tags": [
          "recurring journals"
        ],
        "summary": "Post the recurring journals that are due",
        "description": "Make the entry of every due date on or before `through` (never after today where the\nentity is) of every active recurring journal, in date order, each dated its due date.\n\nEach entry is submitted like an entry typed by hand: the **approval policy** decides for the\ncaller whether it posts or waits for a second person (`pending_approval`). An accrual's entry\nis reversed on the first day of the next period when it posts. It is **idempotent**: a\nrepeated, retried or simultaneous run makes nothing twice (one entry per recurring journal\nand due date, enforced by the database); an `Idempotency-Key` replays the first answer. A\nperiod that cannot be made (a closed period, an inactive account) is `failed` with its error,\nstops that recurring journal at that date and leaves the others running; the next run tries\nit again. An entry the second person rejects is made again by the next run the same way. At\nmost twelve due dates per recurring journal in one run: `more_due` says to run\nagain. Needs an `Idempotency-Key`.",
        "operationId": "run_recurring_journals_v1_recurring_journals_run_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringJournalRunInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringJournalRunResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/recurring-journals/{recurring_journal_id}": {
      "get": {
        "tags": [
          "recurring journals"
        ],
        "summary": "Get a recurring journal",
        "description": "One recurring journal: its lines, schedule, status, next due date and how many entries it\nhas made. 404 when it does not exist.",
        "operationId": "get_recurring_journal_v1_recurring_journals__recurring_journal_id__get",
        "parameters": [
          {
            "name": "recurring_journal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring journal (`GET /v1/recurring-journals`).",
              "examples": [
                "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b"
              ],
              "title": "Recurring Journal Id"
            },
            "description": "Id of the recurring journal (`GET /v1/recurring-journals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringJournalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "recurring journals"
        ],
        "summary": "Change a recurring journal",
        "description": "Change a recurring journal. Omitted fields keep their value; `lines` replaces every line.\nThe next entry is built without being kept to check the change. `frequency` and `start_date`\ncannot change once an entry was made (409): end it and create a new one. A change of `lines`,\n`end_date` or `reverse_next_period` returns an active or paused recurring journal to `draft`,\nso a person activates it again. An end date before the next due date ends it. 409 for an\nended recurring journal; 404, 422 as when creating.",
        "operationId": "update_recurring_journal_v1_recurring_journals__recurring_journal_id__patch",
        "parameters": [
          {
            "name": "recurring_journal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring journal (`GET /v1/recurring-journals`).",
              "examples": [
                "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b"
              ],
              "title": "Recurring Journal Id"
            },
            "description": "Id of the recurring journal (`GET /v1/recurring-journals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringJournalUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringJournalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/recurring-journals/{recurring_journal_id}/activate": {
      "post": {
        "tags": [
          "recurring journals"
        ],
        "summary": "Activate a recurring journal",
        "description": "Make a draft or paused recurring journal run, so that runs make its entries. A person's\nstep: an agent is refused (403). The next entry is built without being kept first. Each entry\na run makes still goes through the approval policy. 409 unless it is a draft or paused.",
        "operationId": "activate_recurring_journal_v1_recurring_journals__recurring_journal_id__activate_post",
        "parameters": [
          {
            "name": "recurring_journal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring journal (`GET /v1/recurring-journals`).",
              "examples": [
                "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b"
              ],
              "title": "Recurring Journal Id"
            },
            "description": "Id of the recurring journal (`GET /v1/recurring-journals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringJournalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/recurring-journals/{recurring_journal_id}/pause": {
      "post": {
        "tags": [
          "recurring journals"
        ],
        "summary": "Pause a recurring journal",
        "description": "Stop an active recurring journal from making entries, with a reason kept in the audit\ntrail, until it is activated again. 409 unless it is active.",
        "operationId": "pause_recurring_journal_v1_recurring_journals__recurring_journal_id__pause_post",
        "parameters": [
          {
            "name": "recurring_journal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring journal (`GET /v1/recurring-journals`).",
              "examples": [
                "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b"
              ],
              "title": "Recurring Journal Id"
            },
            "description": "Id of the recurring journal (`GET /v1/recurring-journals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecurringJournalPause"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringJournalOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/recurring-journals/{recurring_journal_id}/runs": {
      "get": {
        "tags": [
          "recurring journals"
        ],
        "summary": "List the entries a recurring journal made",
        "description": "Every period a run has made or tried for the recurring journal, oldest first: the due\ndate, what came of it (`posted`, `pending_approval`, `rejected`, `failed`), the entry with its\nnumber and status now, its reversal (an accrual's), the error of a failed period, and who ran\nit. 404 when the recurring journal does not exist.",
        "operationId": "list_recurring_journal_runs_v1_recurring_journals__recurring_journal_id__runs_get",
        "parameters": [
          {
            "name": "recurring_journal_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the recurring journal (`GET /v1/recurring-journals`).",
              "examples": [
                "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b"
              ],
              "title": "Recurring Journal Id"
            },
            "description": "Id of the recurring journal (`GET /v1/recurring-journals`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RecurringJournalRunOut"
                  },
                  "title": "Response List Recurring Journal Runs V1 Recurring Journals  Recurring Journal Id  Runs Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/reminders/{notice_id}": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "Get a reminder letter",
        "description": "The letter, the invoices it names, its file, its hand-overs and its state. 404 when\nunknown.",
        "operationId": "get_reminder_v1_reminders__notice_id__get",
        "parameters": [
          {
            "name": "notice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Notice Id"
            },
            "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/reminders/{notice_id}/mark-sent": {
      "post": {
        "tags": [
          "dunning"
        ],
        "summary": "Record that a reminder letter was handed over",
        "description": "Record that a person handed the letter over outside this system: by their own e-mail, by\npost, on the customer's portal. Nothing is sent. The first hand-over starts the clock of the\nnext level. Only a person records (the policy action `send_document`; an agent key answers\n403). 409 `reminder_withdrawn` for a withdrawn letter; 422 for a day before the letter\n(`handover_before_document`), after today (`handover_in_future`) or more than 7 days ago\n(`handover_too_old`): the clock of the next level runs on real days. Needs an\n`Idempotency-Key`.",
        "operationId": "mark_reminder_sent_v1_reminders__notice_id__mark_sent_post",
        "parameters": [
          {
            "name": "notice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Notice Id"
            },
            "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReminderMarkSentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/reminders/{notice_id}/pdf": {
      "get": {
        "tags": [
          "dunning"
        ],
        "summary": "Download a reminder letter",
        "description": "The archived PDF of the letter, as it was made (checked against its SHA-256, which the\nheader `X-Content-SHA256` carries).",
        "operationId": "get_reminder_pdf_v1_reminders__notice_id__pdf_get",
        "parameters": [
          {
            "name": "notice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Notice Id"
            },
            "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`)."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` sends the file as an attachment; `false` inline.",
              "default": false,
              "title": "Download"
            },
            "description": "`true` sends the file as an attachment; `false` inline."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/reminders/{notice_id}/send": {
      "post": {
        "tags": [
          "dunning"
        ],
        "summary": "Send a reminder letter by e-mail",
        "description": "E-mail the archived letter to the customer, as an invoice is sent: to `to` (only the\ncustomer's own addresses) or its billing address, within the organization's hourly limit.\nThe hand-over is recorded with the message id; the next level counts from today.\n\nOnly a person sends (the policy action `send_document`; an agent key answers 403). 409 in a\ntest copy (it never e-mails customers, who may be real ones), `reminder_withdrawn` for a\nwithdrawn letter, `reminder_out_of_date` when an amount on it changed since its day or it is\nmore than 7 days old (withdraw it and make a new one), and when this server has no mail\nserver (download the letter instead); 422 for an address that is not the customer's;\n429 beyond the hourly limit; 502 when the mail server refuses, and nothing is recorded. Needs\nan `Idempotency-Key`.",
        "operationId": "send_reminder_v1_reminders__notice_id__send_post",
        "parameters": [
          {
            "name": "notice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Notice Id"
            },
            "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReminderSendInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "A per-organization limit was reached, e.g. messages sent per hour (`rate_limited`, with `retry_after_seconds`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/reminders/{notice_id}/withdraw": {
      "post": {
        "tags": [
          "dunning"
        ],
        "summary": "Withdraw a reminder letter not handed over",
        "description": "Withdraw a letter that was not handed over (out of date, or made by mistake), with why.\nThe withdrawal is written once: the letter is never sent or recorded after it, and the\ninvoices it named are due their next letter again as if it had not been made. Only a person\nwithdraws (the policy action `release_dunning`; an agent key answers 403). 409\n`reminder_handed_over` once it was handed over, `reminder_withdrawn` when it was withdrawn\nalready. Needs an `Idempotency-Key`.",
        "operationId": "withdraw_reminder_v1_reminders__notice_id__withdraw_post",
        "parameters": [
          {
            "name": "notice_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Notice Id"
            },
            "description": "Reminder letter id (`GET /v1/entities/{entity}/reminders`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReminderWithdrawInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReminderOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/revenue-contracts": {
      "get": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "List revenue contracts",
        "description": "Revenue contracts, the newest first, each with its obligations. Read-only.",
        "operationId": "list_revenue_contracts_v1_revenue_contracts_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's contracts (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's contracts (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "cancelled",
                    "completed",
                    "draft",
                    "pending_approval"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only contracts with this status.",
              "title": "Status"
            },
            "description": "Only contracts with this status."
          },
          {
            "name": "party_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's contracts.",
              "title": "Party Id"
            },
            "description": "Only this customer's contracts."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many contracts, the newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many contracts, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RevenueContractOut"
                  },
                  "title": "Response List Revenue Contracts V1 Revenue Contracts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Create a revenue contract",
        "description": "Create a revenue contract as a **draft**: the customer, the period, the transaction price\n(fixed, net of VAT, in the contract's `currency`, by default the entity's functional currency;\nrevenue is booked in the functional currency, ADR-0050) and its performance obligations, each\nwith its standalone selling price and how it was established (IFRS 15.77-79), or a product\nwhose SSP in force on the start day is taken. Nothing is allocated or scheduled until a second\nperson approves the terms (`POST .../{contract_id}/activate`). A draft's terms are not edited:\ncancel it and create a new one. 404 for an unknown entity, customer, product or account; 422\nwhen an obligation's service period is outside the contract's, a product has no SSP in the\ncurrency, or an account is not a revenue account. Needs an `Idempotency-Key`.",
        "operationId": "create_revenue_contract_v1_revenue_contracts_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RevenueContractInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevenueContractOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/revenue-contracts/{contract_id}": {
      "get": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Get a revenue contract",
        "description": "One revenue contract with its obligations, their allocated prices once it is active, and\nwho approved its terms. 404 when it does not exist.",
        "operationId": "get_revenue_contract_v1_revenue_contracts__contract_id__get",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the revenue contract (`GET /v1/revenue-contracts`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Contract Id"
            },
            "description": "Id of the revenue contract (`GET /v1/revenue-contracts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevenueContractOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/revenue-contracts/{contract_id}/activate": {
      "post": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Activate a revenue contract",
        "description": "Ask for the terms of a draft contract to be approved. **A human decision**: the policy\naction `activate_revenue_contract` denies agents (403, naming the rule), and by default a\nsecond person approves (`POST /v1/approvals/{approval_id}/approve`; never the person who\ncreated the contract or asked). The approval is bound to the digest of the terms. On approval\nthe transaction price is allocated to the obligations by relative SSP and the schedule is\nwritten: a line per month of service for an over-time obligation, one event line for a\npoint-in-time obligation. An organization with one person allows the action in its approval\npolicy, and then a person with the approve scope activates at once. 409 when the contract is\nnot a draft or the customer is not active.",
        "operationId": "activate_revenue_contract_v1_revenue_contracts__contract_id__activate_post",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the revenue contract (`GET /v1/revenue-contracts`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Contract Id"
            },
            "description": "Id of the revenue contract (`GET /v1/revenue-contracts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ActivationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/revenue-contracts/{contract_id}/cancel": {
      "post": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Cancel a revenue contract",
        "description": "Cancel a draft contract, or one waiting for approval (its request is withdrawn), with a\nreason kept in the audit trail. An active contract is not cancelled (409\n`contract_active_not_cancelled`): what it recognised stays, and it is ended early or modified\n(`POST .../{contract_id}/changes`). 409 otherwise.",
        "operationId": "cancel_revenue_contract_v1_revenue_contracts__contract_id__cancel_post",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the revenue contract (`GET /v1/revenue-contracts`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Contract Id"
            },
            "description": "Id of the revenue contract (`GET /v1/revenue-contracts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractCancelInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevenueContractOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/revenue-contracts/{contract_id}/changes": {
      "get": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "List a revenue contract's changes",
        "description": "The changes asked for the contract, the oldest first, with the amounts each named, whether\nit was applied, and the credit notes it made. 404 when the contract does not exist.",
        "operationId": "list_revenue_contract_changes_v1_revenue_contracts__contract_id__changes_get",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the revenue contract (`GET /v1/revenue-contracts`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Contract Id"
            },
            "description": "Id of the revenue contract (`GET /v1/revenue-contracts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ContractChangeOut"
                  },
                  "title": "Response List Revenue Contract Changes V1 Revenue Contracts  Contract Id  Changes Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Ask for an active revenue contract to end early or be modified",
        "description": "Ask a second person to approve a change of an active contract no subscription bills (a\nsubscription's contract changes by the subscription's amendments), as a prospective contract\nmodification (IFRS 15.21(a)): revenue recognised stays, the schedule from the first day not\nrecognised is rewritten.\n\n`end` ends the contract on `end_date`, before its last day, by default at what the schedule\nearned through that day (a part of a month by its days); `modify` gives it a new `price`\nand/or `end_date` (also a later one) from the first day not recognised. When the new price\nis below what was billed, the difference is credited on the invoices, newest first (a credit\nnote per invoice, posted with the change under its approval); above it, the rest is billed\nlater. A further promise at its standalone selling price is a new contract (IFRS 15.20).\n\n**A human decision**: agents are refused (policy action `activate_revenue_contract`, 403),\nand a second person approves (`POST /v1/approvals/{approval_id}/approve`), never the person\nwho asked; approving refuses (409 `terms_changed`) when revenue was recognised or an invoice\nposted since. 409 when the contract is not active or a subscription's, an invoice or credit\nnote billing it is not posted, revenue is recognised after `end_date`, a promise is not\ndelivered or a change waits; 422 for a day outside the term (`end`), a change that changes\nnothing or a price of zero.",
        "operationId": "request_revenue_contract_change_v1_revenue_contracts__contract_id__changes_post",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the revenue contract (`GET /v1/revenue-contracts`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Contract Id"
            },
            "description": "Id of the revenue contract (`GET /v1/revenue-contracts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractChangeInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractChangeAskedOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/revenue-contracts/{contract_id}/changes/preview": {
      "post": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Preview ending a revenue contract early or modifying it",
        "description": "What the change would do, worked out from what is posted now; nothing is written. The same\nrefusals as asking for it.",
        "operationId": "preview_revenue_contract_change_v1_revenue_contracts__contract_id__changes_preview_post",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the revenue contract (`GET /v1/revenue-contracts`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Contract Id"
            },
            "description": "Id of the revenue contract (`GET /v1/revenue-contracts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContractChangeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ContractChangeAmounts"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/revenue-contracts/{contract_id}/schedule": {
      "get": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Get a revenue contract's recognition schedule",
        "description": "The recognition schedule, by obligation and day: what is revenue when, and whether it was\nposted. Empty until the contract is active. 404 when the contract does not exist.",
        "operationId": "get_revenue_contract_schedule_v1_revenue_contracts__contract_id__schedule_get",
        "parameters": [
          {
            "name": "contract_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the revenue contract (`GET /v1/revenue-contracts`).",
              "examples": [
                "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
              ],
              "title": "Contract Id"
            },
            "description": "Id of the revenue contract (`GET /v1/revenue-contracts`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ScheduleLineOut"
                  },
                  "title": "Response Get Revenue Contract Schedule V1 Revenue Contracts  Contract Id  Schedule Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/revenue-obligations/{obligation_id}/satisfy": {
      "post": {
        "tags": [
          "revenue contracts"
        ],
        "summary": "Record that a point-in-time obligation is satisfied",
        "description": "Record the day control of a point-in-time obligation transferred to the customer, with the\nevidence: its schedule line is revenue from that day. **A human decision**: the policy action\n`satisfy_obligation` denies agents (403). 409 unless the contract is active and the obligation\nis open and at a point in time; 422 for a day in the future or before the contract starts.",
        "operationId": "satisfy_revenue_obligation_v1_revenue_obligations__obligation_id__satisfy_post",
        "parameters": [
          {
            "name": "obligation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the performance obligation (`obligations[].id` of the contract).",
              "examples": [
                "9f2a3b4c-5d6e-4f7a-8b9c-0d1e2f3a4b5c"
              ],
              "title": "Obligation Id"
            },
            "description": "Id of the performance obligation (`obligations[].id` of the contract)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SatisfyInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObligationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/roles": {
      "get": {
        "tags": [
          "roles"
        ],
        "summary": "List the roles",
        "description": "The ready-made roles (accounts payable clerk, sales rep, controller, ...) and the\norganization's own, each with its rights, the areas it opens, which sales records its\npeople see, what it allows and does not allow in plain words, and how many people have it.",
        "operationId": "list_roles_v1_roles_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RoleOut"
                  },
                  "title": "Response List Roles V1 Roles Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "post": {
        "tags": [
          "roles"
        ],
        "summary": "Make an own role",
        "description": "A role of the organization's own, from a ready-made one (`based_on`, default `viewer`):\nwhat is not sent is taken from it. An administrator's role opens every area. 409\n`role_title_taken`; 422 `role_template`, `unknown_scopes`, `unknown_area`. Audited as\n`role.create`.",
        "operationId": "create_role_v1_roles_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/roles/areas": {
      "get": {
        "tags": [
          "roles"
        ],
        "summary": "List the areas of the app",
        "description": "The areas a role opens, as the app's sidebar groups them: the general ledger, sales,\npurchasing, the bank, assets and tax, the close, reports, stock and service. A person whose\nrole opens only some of them gets 403 `area_closed` (with `area`) for an operation of another;\nsettings, approvals, search and their own notifications are everyone's, and customers,\nvendors, products, cost centres and exchange rates everyone may read.",
        "operationId": "list_areas_v1_roles_areas_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/AreaOut"
                  },
                  "type": "array",
                  "title": "Response List Areas V1 Roles Areas Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/roles/me": {
      "get": {
        "tags": [
          "roles"
        ],
        "summary": "See what I can open and do",
        "description": "Your own areas, rights and what they allow, in plain words; for a person signed in to the\napp (409 `preview_web_only` for an API key).",
        "operationId": "mine_v1_roles_me_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/roles/people": {
      "get": {
        "tags": [
          "roles"
        ],
        "summary": "List who has which role",
        "description": "Every person of the organization with their role, rights, the areas they open, which sales\nrecords they see, whether that still is their role's, and the last day they used the app.",
        "operationId": "list_people_v1_roles_people_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PersonAccessOut"
                  },
                  "title": "Response List People V1 Roles People Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/roles/people/{user_id}": {
      "put": {
        "tags": [
          "roles"
        ],
        "summary": "Give a person a role",
        "description": "Sets the person's rights, which sales records they see and the areas they open, from\ntheir next request on. A role that lets them approve when their rights did not needs the\n`approver` declaration (422 `approver_declaration_missing`); nobody takes away their own\nadministration (409 `own_admin_scope`). Only a person may give roles. Audited as `role.give`\nwith `user.update`.",
        "operationId": "give_role_v1_roles_people__user_id__put",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the person (`GET /v1/roles/people`).",
              "title": "User Id"
            },
            "description": "Id of the person (`GET /v1/roles/people`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleAssignment"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonAccessOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/roles/people/{user_id}/preview": {
      "get": {
        "tags": [
          "roles"
        ],
        "summary": "See what a person can open and do",
        "description": "What the person sees and may do, in plain words: the areas they open and do not, what\nthey can and cannot do, which sales records they see and when their access ends.",
        "operationId": "preview_v1_roles_people__user_id__preview_get",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the person (`GET /v1/roles/people`).",
              "title": "User Id"
            },
            "description": "Id of the person (`GET /v1/roles/people`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PreviewOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/roles/suggestions": {
      "get": {
        "tags": [
          "roles"
        ],
        "summary": "List unused rights",
        "description": "Rights and areas a person has not used for 90 days, and people who used nothing and did\nnot sign in: each an offer to take it away. Use is counted from `counting_since`; a person\nwhose rights changed in the 90 days is left out until they have been watched as long.",
        "operationId": "list_suggestions_v1_roles_suggestions_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuggestionsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/roles/suggestions/{suggestion_id}/apply": {
      "post": {
        "tags": [
          "roles"
        ],
        "summary": "Take away an unused right",
        "description": "Applies a suggestion that still stands (404 `suggestion_gone` otherwise): the right\nremoved, the area closed, the areas narrowed or the access ended, as Settings would, with\nthe same audit trail.",
        "operationId": "apply_suggestion_v1_roles_suggestions__suggestion_id__apply_post",
        "parameters": [
          {
            "name": "suggestion_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "The suggestion's `id` (`GET /v1/roles/suggestions`).",
              "title": "Suggestion Id"
            },
            "description": "The suggestion's `id` (`GET /v1/roles/suggestions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Applied"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/roles/{role_id}": {
      "patch": {
        "tags": [
          "roles"
        ],
        "summary": "Change an own role",
        "description": "Only the fields sent change; `areas` null opens every area. The people who have the role\nkeep what they were given: the list of people shows them as differing until the role is\ngiven to them again. 409 `role_ready_made` for a ready-made role. Audited as\n`role.update`.",
        "operationId": "update_role_v1_roles__role_id__patch",
        "parameters": [
          {
            "name": "role_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "An own role's id (`GET /v1/roles`); a ready-made role's key is refused.",
              "title": "Role Id"
            },
            "description": "An own role's id (`GET /v1/roles`); a ready-made role's key is refused."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoleUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoleOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "roles"
        ],
        "summary": "Remove an own role",
        "description": "Only while nobody has it (409 `role_in_use`, with `people`); 409 `role_ready_made` for a\nready-made role. Audited as `role.delete`.",
        "operationId": "delete_role_v1_roles__role_id__delete",
        "parameters": [
          {
            "name": "role_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "An own role's id (`GET /v1/roles`); a ready-made role's key is refused.",
              "title": "Role Id"
            },
            "description": "An own role's id (`GET /v1/roles`); a ready-made role's key is refused."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/room-rates/{rate_id}": {
      "delete": {
        "tags": [
          "hospitality"
        ],
        "summary": "Remove a season",
        "description": "Remove a season (audited with its prices); stays already reserved keep their prices.",
        "operationId": "remove_room_rate_v1_room_rates__rate_id__delete",
        "parameters": [
          {
            "name": "rate_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the season (`GET /v1/room-types`).",
              "title": "Rate Id"
            },
            "description": "Id of the season (`GET /v1/room-types`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoomRateOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/room-types": {
      "get": {
        "tags": [
          "hospitality"
        ],
        "summary": "List room types",
        "description": "The room types, by entity and code: rooms, guests a room sleeps, the list price of a night\ntoday, the rooms free tonight and the seasons.",
        "operationId": "list_room_types_v1_room_types_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/RoomTypeOut"
                  },
                  "title": "Response List Room Types V1 Room Types Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "hospitality"
        ],
        "summary": "Add a room type",
        "description": "Let rooms by the night: a service product with its nightly list price (at the VAT rate type\nof accommodation where the VAT area has one), its rooms kept as capacity so no night is let\ntwice, and how many guests a room sleeps. Nothing is posted. Needs an `Idempotency-Key`.",
        "operationId": "create_room_type_v1_room_types_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoomTypeInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoomTypeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/room-types/{product_id}": {
      "get": {
        "tags": [
          "hospitality"
        ],
        "summary": "Get a room type",
        "description": "The room type with its rooms, price, rooms free tonight and seasons.",
        "operationId": "get_room_type_v1_room_types__product_id__get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the room type's product (`GET /v1/room-types`).",
              "title": "Product Id"
            },
            "description": "Id of the room type's product (`GET /v1/room-types`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoomTypeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "hospitality"
        ],
        "summary": "Change a room type",
        "description": "Set its rooms or the guests a room sleeps. 409 (`capacity_booked`) when fewer rooms than\nare booked on a night from today on. Its name and price are the product's.",
        "operationId": "update_room_type_v1_room_types__product_id__patch",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the room type's product (`GET /v1/room-types`).",
              "title": "Product Id"
            },
            "description": "Id of the room type's product (`GET /v1/room-types`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoomTypeUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoomTypeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/room-types/{product_id}/quote": {
      "get": {
        "tags": [
          "hospitality"
        ],
        "summary": "Price a stay",
        "description": "Each night's price of one room and the rooms free, the total, and whether every night\nhas the rooms free. Nothing is booked.",
        "operationId": "quote_stay_v1_room_types__product_id__quote_get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the room type's product (`GET /v1/room-types`).",
              "title": "Product Id"
            },
            "description": "Id of the room type's product (`GET /v1/room-types`)."
          },
          {
            "name": "arrival",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Arrival day.",
              "title": "Arrival"
            },
            "description": "Arrival day."
          },
          {
            "name": "departure",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Departure day, after the last night.",
              "title": "Departure"
            },
            "description": "Departure day, after the last night."
          },
          {
            "name": "rooms",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "Rooms; default 1.",
              "default": 1,
              "title": "Rooms"
            },
            "description": "Rooms; default 1."
          },
          {
            "name": "customer",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Code (or id) of the customer: its currency and prices.",
              "title": "Customer"
            },
            "description": "Code (or id) of the customer: its currency and prices."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/room-types/{product_id}/rates": {
      "post": {
        "tags": [
          "hospitality"
        ],
        "summary": "Add a season",
        "description": "A season's nightly price from its first to its last night, in one currency. 409\n(`room_rate_overlaps`) when it overlaps a season of the room type in that currency. Stays\nalready reserved keep their prices. Needs an `Idempotency-Key`.",
        "operationId": "add_room_rate_v1_room_types__product_id__rates_post",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the room type's product (`GET /v1/room-types`).",
              "title": "Product Id"
            },
            "description": "Id of the room type's product (`GET /v1/room-types`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RoomRateInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RoomRateOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-documents/{document}": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "Get Sales Document",
        "description": "A quote or sales order by id or number: lines (with invoiced and left quantities on an\norder), the linked quote or order, its invoices and hand-overs. The ETag names its version.",
        "operationId": "get_sales_document_v1_sales_documents__document__get",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "sales"
        ],
        "summary": "Update Sales Document",
        "description": "Change a draft (`lines` replaces every line; every line is priced again). A sent quote\ngoes back to draft and is sent again. 409 otherwise; 412 when `If-Match` names an older\nversion.",
        "operationId": "update_sales_document_v1_sales_documents__document__patch",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed quote or order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed quote or order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesDocumentUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/sales-documents/{document}/accept": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Accept Quote",
        "description": "The customer accepted the quote: it is `accepted`, and the open sales order is made from it\n(same customer, currency, terms and lines, dated the day accepted, its own number). Answers\nthe order. 409 `quote_expired` when the quote was no longer valid on that day (change its\nvalid-until day and send it again) or when it is not draft or sent; 409\n`credit_limit_exceeded` when the order would take the customer above its credit limit (the\nquote stays as it is); 422 for a day before the quote or in the future. Only a person records\nthe customer's answer (an agent key answers 403 `agent_records_no_answer`); the customer may\ngive it on the quote's link.",
        "operationId": "accept_quote_v1_sales_documents__document__accept_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed quote or order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed quote or order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcceptInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required",
        "x-if-match": "optional"
      }
    },
    "/v1/sales-documents/{document}/cancel": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Cancel Sales Document",
        "description": "Withdraw a quote not yet decided, or cancel a draft or open order nothing was invoiced on\n(a draft invoice counts: void it first). It keeps its number. 409 `order_invoiced` for an\norder with invoices: close it for the rest instead.",
        "operationId": "cancel_sales_document_v1_sales_documents__document__cancel_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed quote or order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed quote or order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/erp__features__crm__contracts__sales__ReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/sales-documents/{document}/close": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Close Sales Order",
        "description": "Close an open order for the rest, with why (the customer no longer wants it): what was\ninvoiced stays, the rest of each line is closed and no longer invoiced. Final. 409 when\nnothing was invoiced (cancel it instead) or nothing is left.",
        "operationId": "close_sales_order_v1_sales_documents__document__close_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed quote or order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed quote or order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/erp__features__crm__contracts__sales__ReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/sales-documents/{document}/confirm": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Confirm Sales Order",
        "description": "Confirm a draft sales order: it is `open`, to be invoiced, and no longer changes. 409\n`credit_limit_exceeded` when it would take the customer above its credit limit (what it owes,\nits invoices waiting for approval and its open orders, with this one): it stays a draft.",
        "operationId": "confirm_sales_order_v1_sales_documents__document__confirm_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed quote or order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed quote or order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/sales-documents/{document}/decline": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Decline Quote",
        "description": "The customer declined the quote, with why (also once it expired). Final. Only a person\nrecords it (an agent key answers 403).",
        "operationId": "decline_quote_v1_sales_documents__document__decline_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed quote or order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed quote or order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/erp__features__crm__contracts__sales__ReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none",
        "x-if-match": "optional"
      }
    },
    "/v1/sales-documents/{document}/history": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "Sales Document History",
        "description": "The audit events of a quote or order: changes, hand-overs, decisions and invoices, oldest\nfirst.",
        "operationId": "sales_document_history_v1_sales_documents__document__history_get",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AuditEventOut"
                  },
                  "title": "Response Sales Document History V1 Sales Documents  Document  History Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/sales-documents/{document}/invoice": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Invoice Sales Order",
        "description": "Draft the sales invoice of an open order: everything left to invoice, or the quantities\n`lines` asks per order line. Each invoice line names its order line (`sales_line_id`), at\nthe order's price, product and VAT rate type; the VAT is determined on the invoice's day, the\ncustomer's reference becomes the order reference and the order's payment terms the due date.\nAnswers the draft invoice, to be checked, posted and sent like any other\n(`POST /v1/documents/{id}/submit`). 409 for an order that is not open or has nothing left;\n422 for more than is left on a line. Needs an `Idempotency-Key`.",
        "operationId": "invoice_sales_order_v1_sales_documents__document__invoice_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "The ETag of the version you read; a changed quote or order answers 412.",
              "title": "If-Match"
            },
            "description": "The ETag of the version you read; a changed quote or order answers 412."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceOrderInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DocumentOut"
                }
              }
            },
            "headers": {
              "ETag": {
                "description": "The current version, e.g. `\"3\"`; send it back in `If-Match`.",
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "412": {
            "description": "`If-Match` names a version that is no longer current (`precondition_failed`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required",
        "x-if-match": "optional"
      }
    },
    "/v1/sales-documents/{document}/links": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Create Quote Link",
        "description": "Make a link for a sent quote, to give the customer yourself (your own e-mail, a chat): on\nit they see the quote's current version and accept or decline it with their name. The token\nis shown this once; only its hash is kept. A quote this server e-mails carries a link of its\nown. Only a person makes one (an agent key answers 403). 409 for a quote that is not sent;\n422 for an expired one.",
        "operationId": "create_quote_link_v1_sales_documents__document__links_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteLinkInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteLinkIssued"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/sales-documents/{document}/links/{quote_link}/revoke": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Revoke Quote Link",
        "description": "Turn a quote's link off: its page no longer opens. Final; turning it off again changes\nnothing.",
        "operationId": "revoke_quote_link_v1_sales_documents__document__links__quote_link__revoke_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "quote_link",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the link (`online.links[].id`).",
              "title": "Quote Link"
            },
            "description": "Id of the link (`online.links[].id`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QuoteLinkOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "none"
      }
    },
    "/v1/sales-documents/{document}/mark-sent": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Mark Sales Document Sent",
        "description": "Record that a person handed the PDF over outside this system (their own e-mail, post, the\ncustomer's portal); nothing is sent. A draft quote is then `sent` and its version's PDF kept;\n`POST /v1/sales-documents/{document}/links` gives a link to answer it online. Only a person\nrecords. 422 for a day before the document or after today. Needs an `Idempotency-Key`.",
        "operationId": "mark_sales_document_sent_v1_sales_documents__document__mark_sent_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesMarkSentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-documents/{document}/pdf": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "Download a quote or order confirmation",
        "description": "The quote or order confirmation as a PDF in the customer's language, with its lines, VAT,\ntotals and payment terms; a quote says until when it is valid. The header\n`X-Content-SHA256` carries its SHA-256.",
        "operationId": "get_sales_document_pdf_v1_sales_documents__document__pdf_get",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` sends the file as an attachment; `false` inline.",
              "default": false,
              "title": "Download"
            },
            "description": "`true` sends the file as an attachment; `false` inline."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "de",
                    "en",
                    "fr",
                    "it",
                    "sv"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`de`, `fr`, `it`, `en` or `sv`; default the customer's.",
              "title": "Language"
            },
            "description": "`de`, `fr`, `it`, `en` or `sv`; default the customer's."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/sales-documents/{document}/revisions/{revision}/pdf": {
      "get": {
        "tags": [
          "sales"
        ],
        "summary": "Download a version of a quote as the customer got it",
        "description": "The PDF of a version of the quote exactly as it was handed over. 404 for a version that\nwas never handed over.",
        "operationId": "get_quote_revision_pdf_v1_sales_documents__document__revisions__revision__pdf_get",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "revision",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "description": "The version, from 1.",
              "title": "Revision"
            },
            "description": "The version, from 1."
          },
          {
            "name": "download",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "`true` sends the file as an attachment.",
              "default": false,
              "title": "Download"
            },
            "description": "`true` sends the file as an attachment."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/sales-documents/{document}/send": {
      "post": {
        "tags": [
          "sales"
        ],
        "summary": "Send Sales Document",
        "description": "E-mail the PDF to the customer, as an invoice is sent: to `to` (only the customer's own\naddresses) or its billing address, within the organization's hourly limit. A draft quote is\nthen `sent`, and its mail carries a link on which the customer accepts or declines it online\n(ADR-0088); its version's PDF is kept. Only a person sends (the policy action\n`send_document`; an agent key answers 403). 409 in a test copy, for a declined or cancelled\ndocument, or when this server has no mail server (download the PDF instead); 422 for an\nexpired quote or an address that is not the customer's; 429 beyond the hourly limit; 502 when\nthe mail server refuses, and nothing is recorded. Needs an `Idempotency-Key`.",
        "operationId": "send_sales_document_v1_sales_documents__document__send_post",
        "parameters": [
          {
            "name": "document",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`.",
              "examples": [
                "QT-2026-000001"
              ],
              "title": "Document"
            },
            "description": "Quote or sales order id (uuid) or number, e.g. `QT-2026-000001` or `SO-2026-000001`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesSendInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesDocumentCard"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "A per-organization limit was reached, e.g. messages sent per hour (`rate_limited`, with `retry_after_seconds`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "post"
            ]
          },
          {
            "apiKeyAuth": [
              "post"
            ]
          }
        ],
        "x-required-scope": "post",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-tax-returns/{sales_tax_return_id}/approve": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Approve a sales tax filing",
        "description": "A second person approves the filing recorded by someone else (403 for whoever recorded\nit, under the separation-of-duties rule `finalize_own_vat_return`); only an approved filing\nis paid. Answers 409 when already approved or withdrawn. A person's act\n(`finalize_vat_return`).",
        "operationId": "approve_v1_sales_tax_returns__sales_tax_return_id__approve_post",
        "parameters": [
          {
            "name": "sales_tax_return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of a filed sales tax return.",
              "title": "Sales Tax Return Id"
            },
            "description": "Id of a filed sales tax return."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-tax-returns/{sales_tax_return_id}/payment-candidates": {
      "get": {
        "tags": [
          "sales tax"
        ],
        "summary": "List the entries that may have paid a sales tax return",
        "description": "Posted entries of the company dated after the period, with a debit on the state's\naccount that is no sales tax posting, not linked to a return yet: typically the bank entry\nmade by matching the state's debit on the bank worksheet.",
        "operationId": "payment_candidates_v1_sales_tax_returns__sales_tax_return_id__payment_candidates_get",
        "parameters": [
          {
            "name": "sales_tax_return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of a filed sales tax return.",
              "title": "Sales Tax Return Id"
            },
            "description": "Id of a filed sales tax return."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SalesTaxPaymentCandidate"
                  },
                  "title": "Response Payment Candidates V1 Sales Tax Returns  Sales Tax Return Id  Payment Candidates Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/sales-tax-returns/{sales_tax_return_id}/payments": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Link the entry that paid a sales tax return",
        "description": "Links a posted entry as paying the filed return: its amount is its debit on the state's\naccount. The return is `paid` once the links cover `tax_due`. Answers 409 for a withdrawn\nfiling or an entry already linked, 422 for an entry of another company, not posted, dated in\nthe period or without a debit on the account. A person's act (`finalize_vat_return`).",
        "operationId": "link_payment_v1_sales_tax_returns__sales_tax_return_id__payments_post",
        "parameters": [
          {
            "name": "sales_tax_return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of a filed sales tax return.",
              "title": "Sales Tax Return Id"
            },
            "description": "Id of a filed sales tax return."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxPaymentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-tax-returns/{sales_tax_return_id}/payments/{sales_tax_payment_id}/unlink": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Unlink a payment from a sales tax return",
        "description": "Undoes a payment link made by mistake, with the `reason`; the entry stays posted. A\nperson's act (`finalize_vat_return`).",
        "operationId": "unlink_payment_v1_sales_tax_returns__sales_tax_return_id__payments__sales_tax_payment_id__unlink_post",
        "parameters": [
          {
            "name": "sales_tax_return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of a filed sales tax return.",
              "title": "Sales Tax Return Id"
            },
            "description": "Id of a filed sales tax return."
          },
          {
            "name": "sales_tax_payment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the payment link (`payments[].id`).",
              "title": "Sales Tax Payment Id"
            },
            "description": "Id of the payment link (`payments[].id`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-tax-returns/{sales_tax_return_id}/withdraw": {
      "post": {
        "tags": [
          "sales tax"
        ],
        "summary": "Withdraw a sales tax filing",
        "description": "Withdraws a filing recorded by mistake, with the `reason` (kept; the record is not\ndeleted). Answers 409 while payments are linked. A person's act (`finalize_vat_return`).",
        "operationId": "withdraw_v1_sales_tax_returns__sales_tax_return_id__withdraw_post",
        "parameters": [
          {
            "name": "sales_tax_return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of a filed sales tax return.",
              "title": "Sales Tax Return Id"
            },
            "description": "Id of a filed sales tax return."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTaxReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTaxReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-teams": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List sales teams",
        "description": "The organization's sales teams, by name, with their people.",
        "operationId": "list_sales_teams_v1_sales_teams_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SalesTeamOut"
                  },
                  "title": "Response List Sales Teams V1 Sales Teams Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "crm"
        ],
        "summary": "Set up a sales team",
        "description": "A team of sales people; a person may be in several. People who see their team's records\n(`PUT /v1/people/{user_id}/record-visibility`) see the records of everyone in their teams.\n409 `sales_team_exists` for a name in use. Needs an `Idempotency-Key`.",
        "operationId": "create_sales_team_v1_sales_teams_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTeamInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTeamOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/sales-teams/{team_id}": {
      "patch": {
        "tags": [
          "crm"
        ],
        "summary": "Rename a sales team",
        "description": "A new name for the team (409 `sales_team_exists` for one in use).",
        "operationId": "rename_sales_team_v1_sales_teams__team_id__patch",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the team (`GET /v1/sales-teams`).",
              "examples": [
                "6c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
              ],
              "title": "Team Id"
            },
            "description": "Id of the team (`GET /v1/sales-teams`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SalesTeamUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTeamOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "crm"
        ],
        "summary": "Remove a sales team",
        "description": "Remove the team. Its people and their records stay; who sees their team's records sees\nfrom now on what their other teams give them. The audit trail keeps the team's name and\npeople.",
        "operationId": "delete_sales_team_v1_sales_teams__team_id__delete",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the team (`GET /v1/sales-teams`).",
              "examples": [
                "6c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
              ],
              "title": "Team Id"
            },
            "description": "Id of the team (`GET /v1/sales-teams`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/sales-teams/{team_id}/members/{user_id}": {
      "put": {
        "tags": [
          "crm"
        ],
        "summary": "Add a person to a sales team",
        "description": "Add the person to the team (again: nothing changes): anyone of the organization, also\nsomeone invited who has not signed in yet. 404 for someone who is not.",
        "operationId": "add_sales_team_member_v1_sales_teams__team_id__members__user_id__put",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the team (`GET /v1/sales-teams`).",
              "examples": [
                "6c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
              ],
              "title": "Team Id"
            },
            "description": "Id of the team (`GET /v1/sales-teams`)."
          },
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the person (`GET /v1/people`).",
              "examples": [
                "8b1f2c3d-4e5f-4a6b-9c7d-8e9f0a1b2c3d"
              ],
              "title": "User Id"
            },
            "description": "Id of the person (`GET /v1/people`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTeamOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "crm"
        ],
        "summary": "Take a person out of a sales team",
        "description": "Take the person out of the team; their records stay theirs. 404 `not_team_member` when they\nare not in it.",
        "operationId": "remove_sales_team_member_v1_sales_teams__team_id__members__user_id__delete",
        "parameters": [
          {
            "name": "team_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the team (`GET /v1/sales-teams`).",
              "examples": [
                "6c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
              ],
              "title": "Team Id"
            },
            "description": "Id of the team (`GET /v1/sales-teams`)."
          },
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the person (`GET /v1/people`).",
              "examples": [
                "8b1f2c3d-4e5f-4a6b-9c7d-8e9f0a1b2c3d"
              ],
              "title": "User Id"
            },
            "description": "Id of the person (`GET /v1/people`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesTeamOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/sales/activity": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get the sales activity per person",
        "description": "Per person (or agent), the calls, meetings, e-mails and notes they logged, the tasks they\nset and did, the deals they moved to another stage, and the tasks assigned to them that are\nopen and overdue today. Read-only.",
        "operationId": "get_sales_activity_v1_sales_activity_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code (or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code (or id)."
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First day counted; default the 1st of this month.",
              "title": "Date From"
            },
            "description": "First day counted; default the 1st of this month."
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last day counted; default today.",
              "title": "Date To"
            },
            "description": "Last day counted; default today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SalesActivityReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/sales/forecast": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get the sales forecast",
        "description": "By owner and by month: the quota, what is won (closed), and the open deals expected in the\nmonths by forecast category (commit, best case, pipeline; omitted ones left out), the\nforecast (closed plus commit), the best case, attainment and the gap to the quota. Deals\nexpected before the months (`late`) or without a close date (`undated`) are counted, not\nsummed. Read-only.",
        "operationId": "get_forecast_v1_sales_forecast_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code (or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code (or id)."
          },
          {
            "name": "from_month",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First month, `YYYY-MM`; default the first month of this quarter.",
              "title": "From Month"
            },
            "description": "First month, `YYYY-MM`; default the first month of this quarter."
          },
          {
            "name": "to_month",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last month, `YYYY-MM`; default the last month of this quarter.",
              "title": "To Month"
            },
            "description": "Last month, `YYYY-MM`; default the last month of this quarter."
          },
          {
            "name": "rate_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day whose ECB fixing converts other currencies into the entity's functional currency (the latest fixing on or before it); default today.",
              "title": "Rate Day"
            },
            "description": "The day whose ECB fixing converts other currencies into the entity's functional currency (the latest fixing on or before it); default today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ForecastReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/sales/pipeline": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get the pipeline report",
        "description": "The open deals by owner, by stage and by the month they are expected to close: how many,\ntheir value and their value weighted by probability, in the entity's functional currency\n(each deal converted at one ECB fixing) and in each deal's own currency. `late` counts the\nopen deals whose expected close day has passed. Read-only.",
        "operationId": "get_pipeline_report_v1_sales_pipeline_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code (or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code (or id)."
          },
          {
            "name": "owner_user_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this owner's deals.",
              "title": "Owner User Id"
            },
            "description": "Only this owner's deals."
          },
          {
            "name": "rate_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day whose ECB fixing converts other currencies into the entity's functional currency (the latest fixing on or before it); default today.",
              "title": "Rate Day"
            },
            "description": "The day whose ECB fixing converts other currencies into the entity's functional currency (the latest fixing on or before it); default today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PipelineReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/sales/quotas": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "List quotas",
        "description": "Each person's quota per month of the year, in the entity's functional currency.\nRead-only.",
        "operationId": "list_quotas_v1_sales_quotas_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code (or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code (or id)."
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer",
                  "maximum": 2100,
                  "minimum": 2000
                },
                {
                  "type": "null"
                }
              ],
              "description": "Calendar year; default this year.",
              "title": "Year"
            },
            "description": "Calendar year; default this year."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/QuotaOut"
                  },
                  "title": "Response List Quotas V1 Sales Quotas Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "crm"
        ],
        "summary": "Set quotas",
        "description": "Set what each person is to win in a month, in the entity's functional currency; a quota\nalready set takes the new amount (audited with the previous one) and 0 takes it back. Needs\nthe approve scope: targets are set by a manager, never by an agent. 422 for a person who is\nnot of the organization or a person and month named twice. Repeating the request changes\nnothing.",
        "operationId": "set_quotas_v1_sales_quotas_put",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuotaInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/QuotaOut"
                  },
                  "title": "Response Set Quotas V1 Sales Quotas Put"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "none"
      }
    },
    "/v1/sales/win-rate": {
      "get": {
        "tags": [
          "crm"
        ],
        "summary": "Get the win rate",
        "description": "The deals won and lost in the range by owner: how many and their value, the win rate by\ncount and by value, the average deal won and the days it took from creation to close.\nRead-only.",
        "operationId": "get_win_rate_v1_sales_win_rate_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code (or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code (or id)."
          },
          {
            "name": "closed_from",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First close day counted; default 1 January.",
              "title": "Closed From"
            },
            "description": "First close day counted; default 1 January."
          },
          {
            "name": "closed_to",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last close day counted; default today.",
              "title": "Closed To"
            },
            "description": "Last close day counted; default today."
          },
          {
            "name": "rate_day",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "The day whose ECB fixing converts other currencies into the entity's functional currency (the latest fixing on or before it); default today.",
              "title": "Rate Day"
            },
            "description": "The day whose ECB fixing converts other currencies into the entity's functional currency (the latest fixing on or before it); default today."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WinRateReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/saved-report-sources": {
      "get": {
        "tags": [
          "saved reports"
        ],
        "summary": "List what a report can read",
        "description": "The kinds of record a report lists (invoices, bills, customers, vendors, deals, leads,\npayments, purchase orders, subscriptions, journal lines, products), each with its fields:\ntheir type, the values of a list, whether a report may group by them, and the usual columns.",
        "operationId": "list_sources_v1_saved_report_sources_get",
        "parameters": [
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "de",
                "en",
                "fr",
                "it",
                "sv"
              ],
              "type": "string",
              "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`.",
              "default": "en",
              "title": "Language"
            },
            "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ReportSourceOut"
                  },
                  "title": "Response List Sources V1 Saved Report Sources Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/saved-reports/{report_id}": {
      "get": {
        "tags": [
          "saved reports"
        ],
        "summary": "Read a saved report",
        "description": "A report of the caller's or one shared with them (404 `saved_report_not_found` for any\nother).",
        "operationId": "get_saved_report_v1_saved_reports__report_id__get",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedReportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "saved reports"
        ],
        "summary": "Change a saved report",
        "description": "Its name, definition, sharing or schedule; only the fields sent change (`unschedule`\nstops the e-mails). Only its owner (403 `saved_report_not_yours`). A person it is no longer\nshared with loses it from their Home and its e-mails. Audited as `saved_report.update`.",
        "operationId": "update_saved_report_v1_saved_reports__report_id__patch",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SavedReportUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedReportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "saved reports"
        ],
        "summary": "Delete a saved report",
        "description": "Only its owner; it leaves every Home it was pinned to. Audited as\n`saved_report.delete`.",
        "operationId": "delete_saved_report_v1_saved_reports__report_id__delete",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/saved-reports/{report_id}/csv": {
      "get": {
        "tags": [
          "saved reports"
        ],
        "summary": "Download a saved report",
        "description": "Every row (or group) shown, as a CSV file a spreadsheet opens.",
        "operationId": "download_saved_report_v1_saved_reports__report_id__csv_get",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "de",
                "en",
                "fr",
                "it",
                "sv"
              ],
              "type": "string",
              "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`.",
              "default": "en",
              "title": "Language"
            },
            "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "The rows as CSV.",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/saved-reports/{report_id}/pin": {
      "put": {
        "tags": [
          "saved reports"
        ],
        "summary": "Pin to Home",
        "description": "Show the report on the caller's Home; pinning it again changes nothing.",
        "operationId": "pin_saved_report_v1_saved_reports__report_id__pin_put",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedReportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "saved reports"
        ],
        "summary": "Unpin from Home",
        "description": "Take the report off the caller's Home.",
        "operationId": "unpin_saved_report_v1_saved_reports__report_id__pin_delete",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SavedReportOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/saved-reports/{report_id}/result": {
      "get": {
        "tags": [
          "saved reports"
        ],
        "summary": "Run a saved report",
        "description": "The report as of today, as the caller sees it.",
        "operationId": "run_saved_report_v1_saved_reports__report_id__result_get",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "de",
                "en",
                "fr",
                "it",
                "sv"
              ],
              "type": "string",
              "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`.",
              "default": "en",
              "title": "Language"
            },
            "description": "The language of the labels: `en` (default), `de`, `fr`, `it`, `sv`."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/saved-reports/{report_id}/send": {
      "post": {
        "tags": [
          "saved reports"
        ],
        "summary": "E-mail a report now",
        "description": "E-mail the report now to the recipients of its schedule (its owner alone without one),\neach with what they see; the schedule stays as it is. Only its owner, at most once in five\nminutes (409 `saved_report_sent_recently`).",
        "operationId": "send_saved_report_v1_saved_reports__report_id__send_post",
        "parameters": [
          {
            "name": "report_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Report Id"
            },
            "description": "Saved report id (`GET /v1/entities/{entity}/saved-reports`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportSendOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "A per-organization limit was reached, e.g. messages sent per hour (`rate_limited`, with `retry_after_seconds`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/search": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Find records by number or name",
        "description": "Sales invoices and credit notes, purchase bills and credit notes, purchase orders,\njournal entries, payments, customers and vendors of every entity of the organization whose\nnumber, reference, code, name or VAT number holds `q`; subscriptions, revenue contracts and\ndeals (`opportunity`) by number, title or customer (a deal also by its prospect's name),\nproducts by code or name, and plans by name.\n\nNumbers and references (document and payment numbers, the vendor's own invoice number,\npayment, order and buyer references, a journal entry's source reference, VAT numbers) are\ncompared on their letters and digits only, ignoring case, spaces, dashes and dots; names and\ndescriptions as typed, ignoring case. The best matches come first: an exact number, then\none that starts with `q`, then the rest; the number before any other field; then the\nnewest. `matched_field` says where `q` was found.",
        "operationId": "search_v1_search_get",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "description": "What to look for, e.g. `INV-2026-000012`, part of a vendor's invoice number, a QR reference (with or without spaces) or part of a customer's name.",
              "title": "Q"
            },
            "description": "What to look for, e.g. `INV-2026-000012`, part of a vendor's invoice number, a QR reference (with or without spaces) or part of a customer's name."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 20,
              "minimum": 1,
              "description": "Most hits of each type, 1 to 20.",
              "default": 5,
              "title": "Limit"
            },
            "description": "Most hits of each type, 1 to 20."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SearchHit"
                  },
                  "title": "Response Search V1 Search Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/settings/controls": {
      "get": {
        "tags": [
          "settings"
        ],
        "summary": "Get the controls mode",
        "description": "The organization's controls mode: ``ai_reviewer`` (the default, where fixed checks\ndecide each controlled step) or ``four_eyes`` (a second person decides, as before).",
        "operationId": "get_controls_v1_settings_controls_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ControlsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "put": {
        "tags": [
          "settings"
        ],
        "summary": "Set the controls mode",
        "description": "An administrator sets the controls mode (``ai_reviewer`` or ``four_eyes``). The change\napplies at once and is recorded in the audit trail (``controls.change``). Switched to the AI\nreviewer, it decides at once the activations and postings that were waiting for a second\nperson.",
        "operationId": "put_controls_v1_settings_controls_put",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ControlsIn"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ControlsOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/settings/data-sources": {
      "get": {
        "tags": [
          "settings"
        ],
        "summary": "Get the reference-data sources",
        "description": "The reference data this organization needs and whether it arrives (admin).\n\nThe connection to data-vNext (in process or over HTTP, reachable, dataset version,\nlatency, last error); the data points the organization's entities and features need,\neach with the reasons, the registered authority and its status (`ok`, `stale`,\n`no_data`, `error`, or `gap` when no authority is registered); and the other data\npoints of the source register.",
        "operationId": "get_data_sources_v1_settings_data_sources_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataSourcesOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/setup": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "Tell whether the organization waits for its setup",
        "description": "`needed` while the organization has no company (and is not a test organization): the web\nUI then shows its first administrator the setup wizard. Needs the `read` scope.",
        "operationId": "setup_status_v1_setup_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetupStatus"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "setup"
        ],
        "summary": "Set up the organization: Production, then Test",
        "description": "Create the organization's first company from the setup wizard's answers, then its Test\nenvironment.\n\n**Production** is the organization itself: the company (code: the country and `01`, e.g.\n`CA01`) with the chart of accounts of the chosen standard (`GET /v1/setup/options`), the\nperiods of the fiscal year that holds today (a year is named by the calendar year it ends\nin) and the tax return period chosen, in one commit. **Test** is then made as a test copy of\nProduction (`POST /v1/test-copies`), named after the organization with `(Test)`; when it\ncannot be made, Production stands, `test_environment_problem` says why, and an administrator\nmakes it from Settings, Test copies.\n\nRefused with 409 once the organization has a company (a second request makes nothing) and in\na test organization; 422 for an answer the country does not allow. Needs the `admin` scope\nand a person: an agent key is refused (403). Recorded in the audit trail (`org.setup`,\n`entity.create`, `org.test_copy`).",
        "operationId": "complete_setup_v1_setup_post",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetupInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetupDone"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/setup/companies": {
      "post": {
        "tags": [
          "setup"
        ],
        "summary": "Add a further company from the setup wizard's answers",
        "description": "Add a company to an organization that has one, made exactly as `POST /v1/setup` makes\nthe first: the chart of accounts of the chosen standard, the periods of the fiscal year that\nholds today and the tax settings of the return period chosen (`tax_settings`), in one commit,\nunder the `code` given. Unlike `POST /v1/entities`, the answers are checked against what the\ncountry allows (`GET /v1/setup/options`).\n\nRefused with 409 when the code is taken, 422 for an answer the country does not allow, and\n403 for an agent key or a key without the `admin` scope. No Test is made: the organization's\nexisting test copies keep what they were copied from. Recorded in the audit trail\n(`org.company_add`, `entity.create`). A retry with the same `Idempotency-Key` returns the\nfirst answer.",
        "operationId": "add_company_v1_setup_companies_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompanyInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyDone"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/setup/options": {
      "get": {
        "tags": [
          "setup"
        ],
        "summary": "List what the setup wizard offers per country",
        "description": "The countries served (the EU, the United Kingdom, Switzerland and Liechtenstein, the\nUnited States and Canada), each with its currency, the currencies its books may be kept in,\nthe accounting standards a company there may report under (the default first) and the chart\neach starts from, its indirect tax, the return periods allowed, what its tax registration\nnumber is called and the states or provinces to choose from. Needs the `read` scope.",
        "operationId": "setup_options_v1_setup_options_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetupOptions"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/shopify": {
      "get": {
        "tags": [
          "shopify"
        ],
        "summary": "Get Shopify",
        "description": "Whether a shop can be connected here, the permissions its app needs, and each company\nconnected: the shop, its currency, how far its products were read and the last error.",
        "operationId": "get_shopify_v1_shopify_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopifySetup"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/shopify/authorize": {
      "post": {
        "tags": [
          "shopify"
        ],
        "summary": "Start connecting a Shopify shop on its consent page",
        "description": "The shop's consent page for the company's own app: open `url`; the shop sends the browser\nback to `redirect_uri` (which the app must allow) with a query string for\n`POST /v1/shopify/connections/consent`, within 15 minutes. For a shop the app's client\ncredentials cannot reach. 409 in a test copy or when this system has no address to come back\nto.",
        "operationId": "authorize_v1_shopify_authorize_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShopifyAuthorize"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopifyAuthorizeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/shopify/connections": {
      "post": {
        "tags": [
          "shopify"
        ],
        "summary": "Connect a Shopify shop",
        "description": "Connect a company's shop with an app of the company's own: its client id and secret (an\napp made in Shopify's Dev Dashboard and installed on a shop of the app's own organization)\nor a custom app's access token; for any other shop use its consent page\n(`POST /v1/shopify/authorize`). The shop is asked for its name, currency and whether its\nprices include the tax (proving the app). From then on its products come in as products here\nevery 5 minutes (the first round reads them all), and the orders placed from then on as sales\norders. Connecting again replaces the secret. 409\nin a test copy or when the company is connected to another shop; 422 when the shop refuses\nthe app.",
        "operationId": "connect_v1_shopify_connections_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShopifyConnectInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopifyConnection"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/shopify/connections/consent": {
      "post": {
        "tags": [
          "shopify"
        ],
        "summary": "Connect a Shopify shop with its consent page's answer",
        "description": "Finish connecting with the query string the shop's consent page sent the browser back\nwith (only for whoever started it): Shopify's signature is checked with the app's secret and\nthe code traded for the app's lasting token. 422 when the answer is not theirs, too old or not\nsigned by Shopify, or the shop refuses the code; 409 as above.",
        "operationId": "connect_consent_v1_shopify_connections_consent_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShopifyCallbackInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopifyConnection"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/shopify/connections/{shopify_connection_id}": {
      "delete": {
        "tags": [
          "shopify"
        ],
        "summary": "Disconnect Shopify",
        "description": "Disconnect: nothing more is read and the secret is deleted (the app is the company's to\nuninstall in Shopify). The products stay, and so does which variant each is sold as, so\nconnecting the same shop again makes no product twice.",
        "operationId": "disconnect_v1_shopify_connections__shopify_connection_id__delete",
        "parameters": [
          {
            "name": "shopify_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/shopify`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Shopify Connection Id"
            },
            "description": "Id of the connection (`GET /v1/shopify`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/shopify/connections/{shopify_connection_id}/orders": {
      "get": {
        "tags": [
          "shopify"
        ],
        "summary": "List the shop's orders",
        "description": "The shop's orders taken into the books (those placed after the shop was connected), each\nwith its sales order, the invoice of each fulfilment and whether it is paid, and what keeps\nit from being done, in plain words.",
        "operationId": "list_orders_v1_shopify_connections__shopify_connection_id__orders_get",
        "parameters": [
          {
            "name": "shopify_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/shopify`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Shopify Connection Id"
            },
            "description": "Id of the connection (`GET /v1/shopify`)."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "cancelled",
                    "done",
                    "open"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only the orders in this state: `open`, `done` or `cancelled`.",
              "title": "State"
            },
            "description": "Only the orders in this state: `open`, `done` or `cancelled`."
          },
          {
            "name": "problems",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only the orders a step of which was refused.",
              "default": false,
              "title": "Problems"
            },
            "description": "Only the orders a step of which was refused."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "At most this many, the newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "At most this many, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ShopifyOrderOut"
                  },
                  "title": "Response List Orders V1 Shopify Connections  Shopify Connection Id  Orders Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/shopify/connections/{shopify_connection_id}/payouts": {
      "get": {
        "tags": [
          "shopify"
        ],
        "summary": "List the shop's payouts",
        "description": "The payouts of Shopify Payments read from the shop (those of the last 30 days each round,\nfrom the day the shop was connected): what each paid out to the bank, the fees and the\nchargebacks Shopify kept of it, the entry that booked them against the payment provider's\nbalance, whether its bank line was posted to that balance, and what keeps it from being\nbooked, in plain words.",
        "operationId": "list_payouts_v1_shopify_connections__shopify_connection_id__payouts_get",
        "parameters": [
          {
            "name": "shopify_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/shopify`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Shopify Connection Id"
            },
            "description": "Id of the connection (`GET /v1/shopify`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "At most this many, the newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "At most this many, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ShopifyPayoutOut"
                  },
                  "title": "Response List Payouts V1 Shopify Connections  Shopify Connection Id  Payouts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/shopify/connections/{shopify_connection_id}/products": {
      "get": {
        "tags": [
          "shopify"
        ],
        "summary": "List the shop's products",
        "description": "The shop's variants sold here, each with the product it is sold as, its SKU, name, price\nand status as last read.",
        "operationId": "list_variants_v1_shopify_connections__shopify_connection_id__products_get",
        "parameters": [
          {
            "name": "shopify_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/shopify`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Shopify Connection Id"
            },
            "description": "Id of the connection (`GET /v1/shopify`)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "At most this many, by name.",
              "default": 200,
              "title": "Limit"
            },
            "description": "At most this many, by name."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ShopifyVariantOut"
                  },
                  "title": "Response List Variants V1 Shopify Connections  Shopify Connection Id  Products Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/shopify/connections/{shopify_connection_id}/suppliers": {
      "get": {
        "tags": [
          "shopify"
        ],
        "summary": "List the shop's vendors",
        "description": "The vendors the shop's products name, by name, each with the company's vendor who ships\nits goods to the customers (drop shipping), or none when the company ships them itself.",
        "operationId": "list_suppliers_v1_shopify_connections__shopify_connection_id__suppliers_get",
        "parameters": [
          {
            "name": "shopify_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/shopify`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Shopify Connection Id"
            },
            "description": "Id of the connection (`GET /v1/shopify`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ShopifySupplierOut"
                  },
                  "title": "Response List Suppliers V1 Shopify Connections  Shopify Connection Id  Suppliers Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "put": {
        "tags": [
          "shopify"
        ],
        "summary": "Set who ships a shop vendor's goods",
        "description": "Name the company's vendor who ships the goods of one of the shop's vendors straight to the\ncustomers (drop shipping), or none (`vendor` null) when the company ships them itself. From\nthe next round, an order's lines of those goods raise a purchase order of that vendor at their\ncost per item in the shop, sent to the customer's address; those already raised stay. 422\nwhen the vendor is blocked or inactive.",
        "operationId": "set_supplier_v1_shopify_connections__shopify_connection_id__suppliers_put",
        "parameters": [
          {
            "name": "shopify_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/shopify`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Shopify Connection Id"
            },
            "description": "Id of the connection (`GET /v1/shopify`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShopifySupplierInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopifySupplierOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/shopify/connections/{shopify_connection_id}/sync": {
      "post": {
        "tags": [
          "shopify"
        ],
        "summary": "Read the shop now",
        "description": "A round now (they run every 5 minutes): read the products that changed, make products of\nthe new variants and take over new names, prices and whether the shop still sells each; then\nread the orders that changed, make a sales order of each new one and the purchase orders of\nits drop-shipped goods, invoice what was sent and pay the invoices of paid orders to the\npayment provider's balance; then read the payouts and book the fees and chargebacks of those\non their way to the bank. 409 when the shop stopped accepting the app (connect again) or in a\ntest copy.",
        "operationId": "sync_connection_v1_shopify_connections__shopify_connection_id__sync_post",
        "parameters": [
          {
            "name": "shopify_connection_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the connection (`GET /v1/shopify`).",
              "examples": [
                "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a"
              ],
              "title": "Shopify Connection Id"
            },
            "description": "Id of the connection (`GET /v1/shopify`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShopifySyncOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/stock-adjustments": {
      "post": {
        "tags": [
          "inventory"
        ],
        "summary": "Adjust stock",
        "description": "Book goods in or out without a document: damaged, lost or found goods, opening stock.\nGoods going out leave at the moving average, goods coming in at the unit cost given (or the\naverage). The value is posted against the inventory adjustment account, or the account named.\nAn agent's adjustment waits for a person (`status: pending_approval`; the stock changes when\nthe entry is approved). 409 when a warehouse does not hold the quantity going out, on the day\nor any later one. Needs an `Idempotency-Key`.",
        "operationId": "adjust_stock_v1_stock_adjustments_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AdjustmentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockPostingOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/stock-counts": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "List stock counts",
        "description": "Stock counts, newest first, with their lines.",
        "operationId": "list_stock_counts_v1_stock_counts_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "cancelled",
                    "open",
                    "posted"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this status.",
              "title": "Status"
            },
            "description": "Only this status."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, newest first.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many, newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StockCountOut"
                  },
                  "title": "Response List Stock Counts V1 Stock Counts Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "inventory"
        ],
        "summary": "Open a stock count",
        "description": "Open a count of a warehouse on a day (not in the future), with a line for each item to\ncount. One count of a warehouse is open at a time (409). Needs an `Idempotency-Key`.",
        "operationId": "open_stock_count_v1_stock_counts_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StockCountInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockCountOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/stock-counts/{count_id}": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "Get a stock count",
        "description": "One count: the book and counted quantity of each item, and the difference in value.",
        "operationId": "get_stock_count_v1_stock_counts__count_id__get",
        "parameters": [
          {
            "name": "count_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stock count.",
              "title": "Count Id"
            },
            "description": "Id of the stock count."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockCountOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/stock-counts/{count_id}/cancel": {
      "post": {
        "tags": [
          "inventory"
        ],
        "summary": "Cancel a stock count",
        "description": "Cancel an open count; nothing is posted. 409 once posted, or while its differences wait\nfor approval.",
        "operationId": "cancel_stock_count_v1_stock_counts__count_id__cancel_post",
        "parameters": [
          {
            "name": "count_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stock count.",
              "title": "Count Id"
            },
            "description": "Id of the stock count."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockCountOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/stock-counts/{count_id}/lines": {
      "put": {
        "tags": [
          "inventory"
        ],
        "summary": "Enter counted quantities",
        "description": "Record what was counted of the items named (null clears a line). 409 once the count is\nposted or cancelled, or while its differences wait for approval.",
        "operationId": "enter_stock_count_v1_stock_counts__count_id__lines_put",
        "parameters": [
          {
            "name": "count_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stock count.",
              "title": "Count Id"
            },
            "description": "Id of the stock count."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CountLinesInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockCountOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/stock-counts/{count_id}/post": {
      "post": {
        "tags": [
          "inventory"
        ],
        "summary": "Post a stock count",
        "description": "Book the differences of a count whose every line is counted, at the moving average,\nagainst the inventory adjustment account. An agent's differences wait for a person. 409 while\na line is not counted, or once goods moved in the warehouse after the count's day (cancel and\ncount again). Needs an `Idempotency-Key`.",
        "operationId": "post_stock_count_v1_stock_counts__count_id__post_post",
        "parameters": [
          {
            "name": "count_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stock count.",
              "title": "Count Id"
            },
            "description": "Id of the stock count."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockCountOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/stock-items": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "List stock items",
        "description": "The products kept in stock, by code: the quantity in each warehouse, the value and the\nmoving average cost.",
        "operationId": "list_stock_items_v1_stock_items_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "in_stock",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`true`: only those in stock; `false`: only those not.",
              "title": "In Stock"
            },
            "description": "`true`: only those in stock; `false`: only those not."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 5000,
              "minimum": 1,
              "description": "How many, by code.",
              "default": 1000,
              "title": "Limit"
            },
            "description": "How many, by code."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StockItemOut"
                  },
                  "title": "Response List Stock Items V1 Stock Items Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "inventory"
        ],
        "summary": "Keep a product in stock",
        "description": "Start keeping a product in stock: goods sold per unit, with the accounts its stock and its\ncost of goods sold are booked to. 409 when it is kept in stock already; 422 for a product\nthat is not goods sold per unit. Nothing is posted. Needs an `Idempotency-Key`.",
        "operationId": "create_stock_item_v1_stock_items_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StockItemInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockItemOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/stock-items/{product_id}": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "Get a stock item",
        "description": "One stock item with its quantity per warehouse, value and moving average cost.",
        "operationId": "get_stock_item_v1_stock_items__product_id__get",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stock item's product (`GET /v1/stock-items`).",
              "title": "Product Id"
            },
            "description": "Id of the stock item's product (`GET /v1/stock-items`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockItemOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "inventory"
        ],
        "summary": "Change a stock item's accounts",
        "description": "Change its cost of goods sold account, or its inventory account while nothing is in stock\n(409 otherwise). Audited with the previous values.",
        "operationId": "update_stock_item_v1_stock_items__product_id__patch",
        "parameters": [
          {
            "name": "product_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stock item's product (`GET /v1/stock-items`).",
              "title": "Product Id"
            },
            "description": "Id of the stock item's product (`GET /v1/stock-items`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StockItemUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockItemOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/stock-postings": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "List stock postings",
        "description": "Every change of stock, newest first, with its movements and journal entry.",
        "operationId": "list_stock_postings_v1_stock_postings_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "adjustment",
                    "count",
                    "delivery",
                    "receipt",
                    "return",
                    "revaluation",
                    "transfer"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this kind.",
              "title": "Kind"
            },
            "description": "Only this kind."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "pending_approval",
                    "posted",
                    "rejected"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this status.",
              "title": "Status"
            },
            "description": "Only this status."
          },
          {
            "name": "item",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those moving this product (code or id; a code needs `entity`).",
              "title": "Item"
            },
            "description": "Only those moving this product (code or id; a code needs `entity`)."
          },
          {
            "name": "warehouse",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those moving goods in this warehouse (code or id; a code needs `entity`).",
              "title": "Warehouse"
            },
            "description": "Only those moving goods in this warehouse (code or id; a code needs `entity`)."
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Posting date from.",
              "title": "Start"
            },
            "description": "Posting date from."
          },
          {
            "name": "end",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "date"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Posting date to.",
              "title": "End"
            },
            "description": "Posting date to."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, newest first.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many, newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/StockPostingOut"
                  },
                  "title": "Response List Stock Postings V1 Stock Postings Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/stock-postings/{posting_id}": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "Get a stock posting",
        "description": "One stock posting with its movements and journal entry.",
        "operationId": "get_stock_posting_v1_stock_postings__posting_id__get",
        "parameters": [
          {
            "name": "posting_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the stock posting.",
              "title": "Posting Id"
            },
            "description": "Id of the stock posting."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockPostingOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/stock-transfers": {
      "post": {
        "tags": [
          "inventory"
        ],
        "summary": "Move stock between warehouses",
        "description": "Move goods from one warehouse of an entity to another. The value stays with the entity, so\nnothing is posted to the ledger. 409 when the warehouse the goods leave does not hold them.\nNeeds an `Idempotency-Key`.",
        "operationId": "transfer_stock_v1_stock_transfers_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TransferInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StockPostingOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/subscriptions": {
      "get": {
        "tags": [
          "subscriptions"
        ],
        "summary": "List subscriptions",
        "description": "Subscriptions, the newest first, each with its lines. Read-only.",
        "operationId": "list_subscriptions_v1_subscriptions_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's subscriptions (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's subscriptions (code or id)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "active",
                    "cancelled",
                    "draft",
                    "ended",
                    "pending_approval"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only subscriptions with this status.",
              "title": "Status"
            },
            "description": "Only subscriptions with this status."
          },
          {
            "name": "party_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's subscriptions.",
              "title": "Party Id"
            },
            "description": "Only this customer's subscriptions."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many, the newest first.",
              "default": 100,
              "title": "Limit"
            },
            "description": "How many, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SubscriptionOut"
                  },
                  "title": "Response List Subscriptions V1 Subscriptions Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Create a subscription",
        "description": "Create a subscription as a **draft**: the customer, the start day, the committed term (a\nwhole number of billing periods), how it is billed (monthly, quarterly or yearly; in advance or\nin arrears) and its lines, each a recurring product with a quantity, a price per month or year\n(by default the list price in force on the start day) and a discount. It bills in `currency`:\nby default the won opportunity's, else the customer's, else the entity's functional currency;\nprices are taken in that currency, never converted. Every product needs an SSP in it on the\nstart day: it allocates the term's revenue contract. The first invoice is built (not\nkept) to check the customer's tax treatment and the accounts. Nothing is billed until a second\nperson approves the terms (`POST .../{subscription_id}/activate`). A draft's terms are not\nedited: cancel it and create a new one. 404 for an unknown entity, customer, product or\naccount; 422 for a product that is not recurring, inactive, goods, or without a price or SSP\nin the currency (`subscription_currency_unpriced` names the currencies it is priced in), or a\nterm that is not a whole number of billing periods. Needs an `Idempotency-Key`.",
        "operationId": "create_subscription_v1_subscriptions_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscriptionInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/subscriptions/metrics": {
      "get": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Get MRR, ARR and churn",
        "description": "Monthly recurring revenue (MRR) at each month's end (today for the current month), read\nfrom the subscription lines in force that day, never from the ledger: quantity x the price per\nmonth (a yearly price over 12), less the discount. ARR is 12 x MRR. Each month explains the\nchange from the month before with each customer's movement: `new`, `expansion`,\n`contraction`, `churn` and `reactivation`, naming the subscriptions that moved, and gives\nthe customer churn rate, the gross MRR churn rate and the net MRR retention. Amounts are kept\nin each subscription's currency and converted into the entity's functional currency at the\nECB fixing of each month's day; the change of rates is the month's `currency_effect`. At most\n36 months; a month to come is refused (`422 month_in_future`). Read-only.",
        "operationId": "get_subscription_metrics_v1_subscriptions_metrics_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Entity code (or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Entity code (or id)."
          },
          {
            "name": "from_month",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "First month `YYYY-MM`; default the twelfth month back from `to_month`.",
              "title": "From Month"
            },
            "description": "First month `YYYY-MM`; default the twelfth month back from `to_month`."
          },
          {
            "name": "to_month",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^\\d{4}-(0[1-9]|1[0-2])$"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Last month `YYYY-MM`, at the latest the current one; default the current one.",
              "title": "To Month"
            },
            "description": "Last month `YYYY-MM`, at the latest the current one; default the current one."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecurringRevenueReport"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/subscriptions/run": {
      "post": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Bill the subscription periods that are due",
        "description": "Make the invoice of every billing period of an active subscription whose invoice date is on\nor before `through` (never after today where the subscription's company is): in advance on\nthe period's first day, in arrears on the day after its last; when that day is in a closed\nperiod, on the first day of the next open one. Each line bills its obligation in the term's\nrevenue contract (to the contract liability) at the period's part of the term's amount, so the\nperiods of a term add up to its transaction price exactly.\n\nEach invoice is **a draft** for a person to submit, or, with `auto_submit`, is submitted by the\nsystem through the normal path (the approval policy, the open period, the numbering), which the\napproval of the terms authorised. A draft's customer, products, quantities, prices and\nobligations cannot be changed (`409`); a draft voided instead is made again by the next run. It\nis **idempotent**: one invoice per subscription and period, enforced by the database; an\n`Idempotency-Key` replays the first answer. A period that cannot be made (an inactive\ncustomer, the contract's billing cap, terms that no longer match the approved digest) is\n`failed` with its error and stops that subscription at that period, not the run; the next run\ntries it again. At most twelve periods per subscription are billed in one run: `more_due` says\nto run again. The first run after a fully billed term's last day renews it when its terms renew\nit (`auto_renew`) or a renewal was approved (the next term with its own revenue contract, whose\ndue periods it bills too), and otherwise marks it `ended`. A person's request: `403` for an\nagent. Needs an `Idempotency-Key`.",
        "operationId": "run_subscriptions_v1_subscriptions_run_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscriptionRunInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionRunResult"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/subscriptions/{subscription_id}": {
      "get": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Get a subscription",
        "description": "One subscription with its lines, who approved its terms, its term's revenue contract and\neach line's obligation in it. 404 when it does not exist.",
        "operationId": "get_subscription_v1_subscriptions__subscription_id__get",
        "parameters": [
          {
            "name": "subscription_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the subscription (`GET /v1/subscriptions`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Subscription Id"
            },
            "description": "Id of the subscription (`GET /v1/subscriptions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/subscriptions/{subscription_id}/activate": {
      "post": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Ask for a subscription's terms to be approved",
        "description": "Ask for the terms of a draft subscription to be approved. **A second person always\ndecides** (`POST /v1/approvals/{approval_id}/approve`): never the person who drafted the\nsubscription or asked, and never an agent (the policy action `approve_subscription`; an\nagent's request is refused with 403, naming the rule). The approval is bound to the digest of\nthe terms. Approving creates and activates the term's revenue contract in the same\ntransaction: one over-time obligation per line, recognised month by month, its SSP the\nproduct's over the term; the transaction price is what the term bills. The subscription is then\n`active` and the run bills it from its first period. 409 when it is not a draft or the customer\nis not active.",
        "operationId": "activate_subscription_v1_subscriptions__subscription_id__activate_post",
        "parameters": [
          {
            "name": "subscription_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the subscription (`GET /v1/subscriptions`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Subscription Id"
            },
            "description": "Id of the subscription (`GET /v1/subscriptions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionActivationOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/subscriptions/{subscription_id}/amendments": {
      "get": {
        "tags": [
          "subscriptions"
        ],
        "summary": "List a subscription's amendments",
        "description": "The amendments asked for the subscription, the oldest first, each with the amounts it named\nand whether it was applied or rejected. 404 when the subscription does not exist.",
        "operationId": "list_subscription_amendments_v1_subscriptions__subscription_id__amendments_get",
        "parameters": [
          {
            "name": "subscription_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the subscription (`GET /v1/subscriptions`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Subscription Id"
            },
            "description": "Id of the subscription (`GET /v1/subscriptions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AmendmentOut"
                  },
                  "title": "Response List Subscription Amendments V1 Subscriptions  Subscription Id  Amendments Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Ask for an amendment of an active subscription",
        "description": "Ask a second person to approve an amendment of an active subscription's current term.\n`cancel` ends it early: `end_date` is the last day of service (the term's last day ends it there\nwithout renewing). **A second person always decides** (`POST\n/v1/approvals/{approval_id}/approve`), never the person who asked, and never an agent (`403`,\nthe policy action `approve_subscription`). The request names the amounts, worked out from what\nis posted now; approving refuses (`409 terms_changed`) when they changed in between. Approving,\nin one transaction: billing stops after `end_date` (the period it falls in is billed by its days\nif not billed yet); the term's revenue contract is modified prospectively (its price becomes\nwhat the customer now pays, the schedule from the first day not recognised is rewritten,\nrecognised revenue stays); with `proration` `prorate`, the system posts a credit note per period\nbilled past `end_date` for its unused part, naming the obligations; with `none`, what was billed\nis kept and its part for service not given is revenue on `end_date`. The run then ends the\nsubscription after `end_date`. `409` when the subscription is not active or already ends, has\nan invoice not posted, revenue recognised after `end_date`, or an amendment waiting; `422` when\n`end_date` is outside the current term or leaves nothing to bill.\n\n`renew` (for a subscription whose terms do not renew it, `auto_renew` false) renews it into the\nnext term: as long as the term, its months counted from the start day, at the prices in force\nraised by `renewal_uplift_percent`, with its own revenue contract activated in the approver's\nname. Approved before the term ends, the first billing run after its last day starts the next\nterm; approved after, it starts at once. `409` when the subscription is not active, ends early,\nrenews itself (`renewal_automatic`) or its renewal is approved already.",
        "operationId": "request_subscription_amendment_v1_subscriptions__subscription_id__amendments_post",
        "parameters": [
          {
            "name": "subscription_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the subscription (`GET /v1/subscriptions`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Subscription Id"
            },
            "description": "Id of the subscription (`GET /v1/subscriptions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AmendmentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AmendmentRequestOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/subscriptions/{subscription_id}/amendments/preview": {
      "post": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Preview an amendment of a subscription",
        "description": "What an amendment would change, worked out from what is posted now; nothing is written. For\n`cancel`: the term's new price (the revenue contract's transaction price), the part earned by\nthe service through `end_date`, and a credit per period billed past it. For `renew`: the next\nterm's days and price (`new_price`). The errors are those of the request below.",
        "operationId": "preview_subscription_amendment_v1_subscriptions__subscription_id__amendments_preview_post",
        "parameters": [
          {
            "name": "subscription_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the subscription (`GET /v1/subscriptions`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Subscription Id"
            },
            "description": "Id of the subscription (`GET /v1/subscriptions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AmendmentInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AmendmentAmounts"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read",
        "x-idempotency": "none"
      }
    },
    "/v1/subscriptions/{subscription_id}/cancel": {
      "post": {
        "tags": [
          "subscriptions"
        ],
        "summary": "Cancel a subscription",
        "description": "Cancel a draft subscription, or one waiting for approval (its request is withdrawn; only a\nperson withdraws it), with a reason kept in the audit trail. An active subscription is not\ncancelled here: it is ended early by an amendment (`POST .../{subscription_id}/amendments`).\n409 otherwise.",
        "operationId": "cancel_subscription_v1_subscriptions__subscription_id__cancel_post",
        "parameters": [
          {
            "name": "subscription_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the subscription (`GET /v1/subscriptions`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Subscription Id"
            },
            "description": "Id of the subscription (`GET /v1/subscriptions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubscriptionCancelInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubscriptionOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/subscriptions/{subscription_id}/invoices": {
      "get": {
        "tags": [
          "subscriptions"
        ],
        "summary": "List a subscription's billed periods",
        "description": "The billing periods the run billed, in order, each with its invoice or, for a failed\nattempt, the error (the next run tries it again). 404 when the subscription does not exist.",
        "operationId": "list_subscription_invoices_v1_subscriptions__subscription_id__invoices_get",
        "parameters": [
          {
            "name": "subscription_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the subscription (`GET /v1/subscriptions`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Subscription Id"
            },
            "description": "Id of the subscription (`GET /v1/subscriptions`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SubscriptionInvoiceOut"
                  },
                  "title": "Response List Subscription Invoices V1 Subscriptions  Subscription Id  Invoices Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/support/cases": {
      "get": {
        "tags": [
          "support"
        ],
        "summary": "List support cases",
        "description": "The cases to work on, the next one due first (the closed ones last, the latest first),\neach with its service levels: when the first reply and the resolution are due, whether they\nwere met, are running, stand still (waiting on the customer) or are breached.",
        "operationId": "list_cases_v1_support_cases_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's (code or id).",
              "title": "Entity"
            },
            "description": "Only this company's (code or id)."
          },
          {
            "name": "queue",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this queue's (code or id; needs `entity`).",
              "title": "Queue"
            },
            "description": "Only this queue's (code or id; needs `entity`)."
          },
          {
            "name": "show",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "active",
                "all",
                "closed",
                "open",
                "waiting"
              ],
              "type": "string",
              "description": "`active` (open and waiting, the default), `open`, `waiting`, `closed` or `all`.",
              "default": "active",
              "title": "Show"
            },
            "description": "`active` (open and waiting, the default), `open`, `waiting`, `closed` or `all`."
          },
          {
            "name": "assignee",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "`me`, `none` (nobody yet) or a person's id (`GET /v1/people`).",
              "title": "Assignee"
            },
            "description": "`me`, `none` (nobody yet) or a person's id (`GET /v1/people`)."
          },
          {
            "name": "party_id",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "format": "uuid"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this customer's.",
              "title": "Party Id"
            },
            "description": "Only this customer's."
          },
          {
            "name": "breached",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "description": "Only those with a breached service level.",
              "default": false,
              "title": "Breached"
            },
            "description": "Only those with a breached service level."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "description": "Text in the number, subject or address.",
              "title": "Q"
            },
            "description": "Text in the number, subject or address."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 1000,
              "minimum": 1,
              "description": "How many.",
              "default": 200,
              "title": "Limit"
            },
            "description": "How many."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CaseOut"
                  },
                  "title": "Response List Cases V1 Support Cases Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Open a support case",
        "description": "A case from a call, a visit or a form: what the customer asked (`description`), the\nqueue, priority, customer, contact or requester, and who works it (none: the queue assigns\nwhen it does). It gets the company's next number and its service levels. An agent may open\none. Needs an `Idempotency-Key`.",
        "operationId": "create_case_v1_support_cases_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/support/cases/{case_id}": {
      "get": {
        "tags": [
          "support"
        ],
        "summary": "Get a case",
        "description": "The case with its messages (oldest first, drafts included), the addresses a reply may go\nto and whether replies can be e-mailed from here.",
        "operationId": "get_case_v1_support_cases__case_id__get",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "patch": {
        "tags": [
          "support"
        ],
        "summary": "Triage a case",
        "description": "Change the subject, queue, priority, person, customer, contact or requester (null clears\nthe last four); a new queue or priority sets the due times anew from the case's start. An\nagent may triage. 409 `support_case_closed` for a closed case.",
        "operationId": "update_case_v1_support_cases__case_id__patch",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CaseUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/support/cases/{case_id}/notes": {
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Add an internal note",
        "description": "A note for colleagues on the case; it never leaves the system. An agent may add one.",
        "operationId": "add_note_v1_support_cases__case_id__notes_post",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/support/cases/{case_id}/replies": {
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Write a reply",
        "description": "A reply to the customer: `draft` keeps it for a person (an agent drafts only); `send`\ne-mails it now in the company's name, answered to the queue's inbox, with the case number in\nthe subject; `record` notes it was answered elsewhere. Sending or recording is a person's\n(403 `support_send_agent`); it meets the first-reply level, and the case then waits on the\ncustomer (or `then`). 409 in a test copy or without a mail server for `send`; 422 for an\naddress that is not the requester's, the contact's or the customer's; 429 beyond the hourly\nlimit. Needs an `Idempotency-Key`.",
        "operationId": "add_reply_v1_support_cases__case_id__replies_post",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplyInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/support/cases/{case_id}/replies/{message_id}": {
      "patch": {
        "tags": [
          "support"
        ],
        "summary": "Change a draft reply",
        "description": "Change a draft's text or recipients. 409 `support_not_draft` once it was sent or\ndiscarded.",
        "operationId": "update_reply_v1_support_cases__case_id__replies__message_id__patch",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the message (the case's `messages`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Message Id"
            },
            "description": "Id of the message (the case's `messages`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DraftUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/support/cases/{case_id}/replies/{message_id}/discard": {
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Discard a draft reply",
        "description": "Drop a draft: it is kept, discarded, and no longer shown on the case.",
        "operationId": "discard_reply_v1_support_cases__case_id__replies__message_id__discard_post",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the message (the case's `messages`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Message Id"
            },
            "description": "Id of the message (the case's `messages`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/support/cases/{case_id}/replies/{message_id}/send": {
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Send a draft reply",
        "description": "Send the draft by e-mail (`via` `email`) or record that it was answered elsewhere\n(`outside`). A person's (403 `support_send_agent`). Needs an `Idempotency-Key`.",
        "operationId": "send_reply_v1_support_cases__case_id__replies__message_id__send_post",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the message (the case's `messages`).",
              "examples": [
                "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d"
              ],
              "title": "Message Id"
            },
            "description": "Id of the message (the case's `messages`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "anyOf": [
                  {
                    "$ref": "#/components/schemas/ReplySendInput"
                  },
                  {
                    "type": "null"
                  }
                ],
                "title": "Body"
              },
              "example": {
                "via": "email",
                "then": "waiting"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "A per-organization limit was reached, e.g. messages sent per hour (`rate_limited`, with `retry_after_seconds`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/support/cases/{case_id}/status": {
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Close, reopen or set a case to wait",
        "description": "`closed` (with how it was resolved), `waiting` (on the customer: the resolution clock\nstands still) or `open` again. A person's call: 403 `support_status_agent` for an agent.",
        "operationId": "set_case_status_v1_support_cases__case_id__status_post",
        "parameters": [
          {
            "name": "case_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the case (`GET /v1/support/cases`).",
              "examples": [
                "3e4f5a6b-7c8d-4e9f-8a0b-1c2d3e4f5a6b"
              ],
              "title": "Case Id"
            },
            "description": "Id of the case (`GET /v1/support/cases`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StatusInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaseDetail"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/support/inbound": {
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Hand over an e-mail to a queue's inbox",
        "description": "For a mail service or an integration that receives the inbox's mail: the e-mail becomes a\ncase of the queue whose inbox it was sent to, or a message of the case it answers (by\nIn-Reply-To, References or the case number in the subject), which it reopens. Kept once per\nMessage-ID (`duplicate`). null for an automatic message that answers no case. 422\n`support_inbox_unknown` when no active queue has an address it went to. A linked Google\nmailbox that receives the inbox's mail hands it over by itself. Needs an\n`Idempotency-Key`.",
        "operationId": "receive_mail_v1_support_inbound_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InboundInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/InboundOut"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Response Receive Mail V1 Support Inbound Post"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/support/queues": {
      "get": {
        "tags": [
          "support"
        ],
        "summary": "List support queues",
        "description": "The support queues by code: inbox address, service levels, working hours, members and how\nmany cases are open.",
        "operationId": "list_queues_v1_support_queues_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this company's (code or id).",
              "title": "Entity"
            },
            "description": "Only this company's (code or id)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/QueueOut"
                  },
                  "title": "Response List Queues V1 Support Queues Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "support"
        ],
        "summary": "Add a support queue",
        "description": "A queue of a company: its code and name, the address customers write to (its inbox),\nthe service levels per priority in working minutes, the working hours (none: around the clock)\nin the company's time zone, its members and whether it assigns new cases to them. 409\n`support_queue_exists` for a code in use, `support_address_taken` for an inbox another queue\nhas. Needs an `Idempotency-Key`.",
        "operationId": "create_queue_v1_support_queues_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueueInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueueOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/support/queues/{queue_id}": {
      "patch": {
        "tags": [
          "support"
        ],
        "summary": "Change a support queue",
        "description": "Change what the request names: name, inbox (`\"\"` removes it), service levels (the whole\nset), working hours (null: around the clock), members (the whole list), automatic\nassignment, or `active` (false: no new case goes to it). New targets apply to the cases\nopened, or moved to another priority or queue, from then on.",
        "operationId": "update_queue_v1_support_queues__queue_id__patch",
        "parameters": [
          {
            "name": "queue_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the queue (`GET /v1/support/queues`).",
              "examples": [
                "4f5a6b7c-8d9e-4f0a-9b1c-2d3e4f5a6b7c"
              ],
              "title": "Queue Id"
            },
            "description": "Id of the queue (`GET /v1/support/queues`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueueUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueueOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/test-copies": {
      "get": {
        "tags": [
          "test copies"
        ],
        "summary": "List the test copies of the organization",
        "description": "The test organizations made from this one, oldest first. Needs the `admin` scope.",
        "operationId": "list_test_copies_v1_test_copies_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CopyOut"
                  },
                  "title": "Response List Test Copies V1 Test Copies Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "post": {
        "tags": [
          "test copies"
        ],
        "summary": "Make a test copy of the organization",
        "description": "Make a new **test organization** that is a clone of this one, to try things out or work\non without touching the real books: everything of the organization comes across exactly as it\nis, under new ids: its companies (entities), fiscal years and periods, the chart of accounts,\nsettings, customers, vendors, products, contracts and subscriptions, every journal entry,\ninvoice, bill, payment, asset, bank statement, VAT return, stored document, plan and close, the\naudit trail, and its people with their roles (as invited: they sign in to the copy with their\nusual sign-in). The copy's books are proven to be the organization's own before the answer is\ngiven: every hash chain verifies and every account of every company has the same balance in\nevery currency (409 otherwise, and nothing is made). API keys, sessions, the security log and\nexports stay behind.\n\nWith `masked`, who the business partners are does not come across: the names, e-mails,\ne-invoicing addresses, streets and numbers, IBANs and contacts of customers, vendors and\nprospects, the counterparties of bank lines and the addresses documents were sent to become\nmock values (`Customer 001`, `contact-001@example.com`), the same real value always the same\nmock, wherever they appear in free text (descriptions, notes, payment files, the audit trail);\nnotes about them, remittances and the descriptions of journal entries typed by hand or booked\nfrom a bank line (a salary naming its employee) become `(masked)`, wherever they were copied,\nand stored files a placeholder; the audit trail and approvals keep only what happened\n(amounts, codes, dates, statuses), not about whom, and a change of a partner's details still\nwaiting arrives rejected. Nothing else changes: codes, references, currencies and actions keep\ntheir values. The organization's own setup (companies, bank accounts, chart of\naccounts, products, settings, including a partner's name it holds, such as an account named\nafter a customer), its intercompany partners, partners' codes, amounts, dates, tax data and the\npeople who sign in stay exactly as they are, so the books are still proven to be the\norganization's own. For testing with\npeople who should not see the real customers and vendors.\n\nEach person of the organization finds the test organization in the list of organizations\nwhen signing in, labelled as a test. Nothing leaves a test copy: no e-mail to a customer, no\npayment file and no e-invoice (its customers, vendors and banks are the real ones); remove it\nwith `DELETE /v1/test-copies/{copy_id}` when it is no longer needed. A test organization\ncannot itself be copied (409), and an organization has at most 5 test copies at a time (409).\nNeeds the `admin` scope and a person: an agent key is refused (403). Recorded in the audit\ntrail of both organizations (`org.test_copy`).\n\nA retry with the same `Idempotency-Key` returns the first answer and makes nothing more.",
        "operationId": "make_test_copy_v1_test_copies_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopyRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/test-copies/{copy_id}": {
      "delete": {
        "tags": [
          "test copies"
        ],
        "summary": "Remove a test copy",
        "description": "Remove a test organization made from this one, with everything in it: its books, its\nsetup and its people's access to it. The answer is `202` with `remove_requested_at` set: from\nthen on nobody can sign in to the copy or change anything in it. It is deleted for good\nbetween one and two hours later (one copy after the other, the one asked for first), and\nthen leaves `GET /v1/test-copies`; it no longer counts towards the 5 copies. Only test\ncopies of this organization can be removed (404 for any other id); a real organization\nnever can. Asking again changes nothing. Needs the `admin` scope and a person: an agent key\nis refused (403). Recorded in the audit trail (`org.test_copy_remove`) and, when it is\ndeleted, in the platform's audit.",
        "operationId": "remove_test_copy_v1_test_copies__copy_id__delete",
        "parameters": [
          {
            "name": "copy_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id (uuid) of the test copy.",
              "title": "Copy Id"
            },
            "description": "Id (uuid) of the test copy."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/test-copies/{copy_id}/refresh": {
      "post": {
        "tags": [
          "test copies"
        ],
        "summary": "Refresh a test copy from the organization",
        "description": "Clone this organization again into one of its test copies, as it is now: **everything in\nthe copy is replaced**, and whatever was done in it is lost (entries, documents, settings,\nits audit trail; only its log of security events stays). The copy keeps its id and name, so\nits people find it where it was; they are signed out of it. Its books are proven to be this\norganization's own, as when a copy is made (409 otherwise, and the copy stays as it was). A\nmasked copy is masked again. `cloned_at` tells when it happened.\n\n404 for anything that is not a test copy of this organization, 409 for a copy whose removal\nwas asked for. Needs the `admin` scope and a person: an agent key is refused (403). Recorded in\nthe audit trail of both organizations (`org.test_copy_refresh`). A retry with the same\n`Idempotency-Key` returns the first answer and refreshes nothing more.",
        "operationId": "refresh_test_copy_v1_test_copies__copy_id__refresh_post",
        "parameters": [
          {
            "name": "copy_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id (uuid) of the test copy.",
              "title": "Copy Id"
            },
            "description": "Id (uuid) of the test copy."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "required"
      }
    },
    "/v1/test-copies/{copy_id}/schedule": {
      "put": {
        "tags": [
          "test copies"
        ],
        "summary": "Set when a test copy is refreshed by itself",
        "description": "Have the copy refreshed by itself, as `POST /v1/test-copies/{copy_id}/refresh` does:\n`nightly` refreshes it every night, `weekly` once a week (a week after it was last filled),\n`off` stops it. Every refresh replaces everything in the copy, so whatever was done in it\nsince is lost; a copy that cannot be refreshed stays as it was until the next night. The\nrefreshes are recorded in the audit trail of both organizations (`org.test_copy_refresh`),\nwith who set the schedule. 404 and 409 as for a refresh. Needs the `admin` scope and a\nperson: an agent key is refused (403). Recorded in the audit trail\n(`org.test_copy_schedule`); setting the schedule it has changes nothing.",
        "operationId": "schedule_test_copy_v1_test_copies__copy_id__schedule_put",
        "parameters": [
          {
            "name": "copy_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id (uuid) of the test copy.",
              "title": "Copy Id"
            },
            "description": "Id (uuid) of the test copy."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ScheduleRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CopyOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/users": {
      "get": {
        "tags": [
          "users"
        ],
        "summary": "List users",
        "description": "The people of the organization (invited, active or disabled) ordered by email, with\ntheir scopes. Only a human with the admin scope may list them (403 otherwise).",
        "operationId": "list_users_v1_users_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/UserOut"
                  },
                  "type": "array",
                  "title": "Response List Users V1 Users Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Invite a user",
        "description": "Invite a person by email; they sign in to the web UI with the Google account of that\naddress, or, without one, with the address and a password, which activates the user. When\npassword sign-in is configured, Google also e-mails them the link that sets their password\n(as `POST /v1/users/{user_id}/password-email`), except to an address of the deployment's\nGoogle Workspace domains, whose people sign in with Google. The access is a `role` preset\n(`viewer` by default) or an explicit list of `scopes`, which wins when both are sent. Only a\nhuman with the admin scope may invite (403 otherwise); 409 when the address is already a user\nof this organization; 422 for an unknown scope; 502 when Google refuses the e-mail (nobody is\ninvited, the request can be repeated). The new user has status `invited`.\n\nAn external auditor (the `auditor` role) is invited with `access_until`, the moment their\naccess ends (422 `access_until_missing` without it): they read everything and change\nnothing, and every request they make goes to the access log (`GET /v1/access-log`).",
        "operationId": "invite_user_v1_users_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InviteInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InvitedUser"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/users/{user_id}": {
      "patch": {
        "tags": [
          "users"
        ],
        "summary": "Update a user",
        "description": "Change a user's name, access or status. Send a `role` preset or a list of `scopes`, not\nboth (422); only the fields sent change. Setting the status to `disabled` also ends the\nuser's sessions. `access_until` moves the end of the user's access (null removes it, except\nfor an external auditor). You cannot remove your own admin scope, disable yourself or set an\nend to your own access (409). Only a\nhuman with the admin scope may do this (403 otherwise); an unknown user answers 404.",
        "operationId": "update_user_v1_users__user_id__patch",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "User id (`GET /v1/users`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "User Id"
            },
            "description": "User id (`GET /v1/users`)."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UserUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UserOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/users/{user_id}/passkeys/reset": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "Reset a user's passkeys",
        "description": "For a person who lost every device with a passkey: remove their passkeys and end their\nsessions; their next sign-in creates a new first passkey. Only a human administrator may do\nthis, with a passkey touch within five minutes (403 `passkey_step_up`), and not for\nthemselves (409). For a person who is also a user of another organization (other than this\none's test copies) it answers 409 `passkey_reset_elsewhere`: their passkeys open that\norganization too, so the platform's operator resets them. 404 for an unknown user. Recorded\nin the audit trail (`user.passkey_reset`) and as a security event (`passkey.reset`).",
        "operationId": "reset_passkeys_v1_users__user_id__passkeys_reset_post",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "User id (`GET /v1/users`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "User Id"
            },
            "description": "User id (`GET /v1/users`)."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasskeyReset"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/users/{user_id}/password-email": {
      "post": {
        "tags": [
          "users"
        ],
        "summary": "E-mail a user a link to set their password",
        "description": "Have Google e-mail the user a link that sets the password of their account at Google\nIdentity Platform, for a person without a Google account (ADR-0037). It creates the account\nwhen there is none, sets a first password and resets a forgotten one alike; an existing\npassword keeps working until the link is used. Google sends the e-mail; the ERP never sees\nthe password. Only a human with the admin scope may do this (403 otherwise); 404 for an\nunknown user; 409 for a disabled user or when password sign-in is not configured; 502 when\nGoogle refuses. Recorded in the audit trail (`user.password_email`).",
        "operationId": "send_password_email_v1_users__user_id__password_email_post",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "User id (`GET /v1/users`).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "User Id"
            },
            "description": "User id (`GET /v1/users`)."
          }
        ],
        "responses": {
          "202": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PasswordEmailSent"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/vat-registers/check": {
      "post": {
        "tags": [
          "parties"
        ],
        "summary": "Check a VAT number against its public register",
        "description": "Ask the public register whether a VAT number is valid, and for the registered name.\n\nEU numbers (and XI) are checked in VIES, Swiss UIDs in the UID register, UK numbers with\nHMRC (when the server is configured for it). The answer is advisory: `invalid` says the\nregister does not know the number as registered for VAT, `unavailable` that it did not\nanswer in time and the check can be repeated. Definite answers are kept for a day\n(`cached`). Nothing is stored or changed. The number and name go in the body, never the\nURL. An organization may make 30 checks a minute that reach a register (cached answers do\nnot count); beyond that the answer is 429 with `retry_after_seconds`.",
        "operationId": "check_vat_number_v1_vat_registers_check_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegisterCheckInput"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegisterCheck"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/vat-returns": {
      "get": {
        "tags": [
          "vat returns"
        ],
        "summary": "List VAT returns",
        "description": "Summaries of the organization's VAT returns, newest period first, without their\nboxes: status, payable, the settlement entry and the number of errors and warnings.\nOpen one with `GET /v1/vat-returns/{return_id}` for the boxes and issues. All filters\nare optional and combine; discarded and superseded returns are listed unless filtered.",
        "operationId": "list_returns_v1_vat_returns_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only returns of this entity, by code.",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only returns of this entity, by code."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "annual_summary",
                    "oss_return",
                    "pst_return_bc",
                    "pst_return_sk",
                    "qst_return",
                    "recapitulative_statement",
                    "rst_return_mb",
                    "vat_return"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this kind: `vat_return`, `recapitulative_statement`, `qst_return`, `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary`, `oss_return`.",
              "title": "Kind"
            },
            "description": "Only this kind: `vat_return`, `recapitulative_statement`, `qst_return`, `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary`, `oss_return`."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only returns with this status: `draft`, `pending_approval`, `final`, `amending`, `superseded` or `discarded`.",
              "examples": [
                "final"
              ],
              "title": "Status"
            },
            "description": "Only returns with this status: `draft`, `pending_approval`, `final`, `amending`, `superseded` or `discarded`."
          },
          {
            "name": "year",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "integer"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only returns whose period starts in this calendar year.",
              "examples": [
                2026
              ],
              "title": "Year"
            },
            "description": "Only returns whose period starts in this calendar year."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/VatReturnSummary"
                  },
                  "title": "Response List Returns V1 Vat Returns Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Compute a draft VAT return",
        "description": "Computes a draft return (`vat_return`, the EU `recapitulative_statement`, or the\n`annual_summary` where the country has one, the Spanish Modelo 390) for an\nentity and period (`2026-08`, `2026-Q3`, `2026-H2` or `2026`) from the posted, tax-tagged\njournal lines, and stores which line fills which box. An existing draft of the period is\nrecomputed instead. The result carries the boxes, the reconciliation with the VAT accounts\nand the issues. Answers 409 when the period already has a pending, final or amending\nreturn (amend it instead) and 422 for a malformed period or an adjustment on a box the\nledger fills or computes.",
        "operationId": "create_return_v1_vat_returns_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatReturnInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}": {
      "get": {
        "tags": [
          "vat returns"
        ],
        "summary": "Get a VAT return",
        "description": "The return as stored: status, payable, the settlement entry and the computed `result`\n(form, boxes with their Ziffer or Kennzahl, reconciliation, issues, adjustments). A final\nreturn and its result do not change; a draft shows the state of its last computation.",
        "operationId": "get_return_v1_vat_returns__return_id__get",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/vat-returns/{return_id}/amend": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Open a correction of a final VAT return",
        "description": "Opens a correction of a `final` return: the original becomes `amending`, the period's\nVAT postings are unlocked, and a new draft (its `amends_id` names the original) is\ncomputed from the current ledger. Finalising the correction books only the difference to\nthe original in its settlement and marks the original `superseded`; discarding the\ncorrection puts the original back in force. Takes no body. Needs the approval policy\naction `finalize_vat_return` (403 when denied) and answers 409 unless the return is\n`final`.",
        "operationId": "amend_v1_vat_returns__return_id__amend_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "approve"
            ]
          },
          {
            "apiKeyAuth": [
              "approve"
            ]
          }
        ],
        "x-required-scope": "approve",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}/boxes/{box}/lines": {
      "get": {
        "tags": [
          "vat returns"
        ],
        "summary": "List the ledger lines behind a box",
        "description": "The drill-down of one box: every journal line that was routed into it, with its\njournal entry, account, document, counterparty, the rule that routed it and the amount\nit contributes in the return's currency. Ordered by entry date and number. A box that\nis computed from other boxes, filled by adjustment only, or unknown has no lines (an\nempty list).",
        "operationId": "box_lines_v1_vat_returns__return_id__boxes__box__lines_get",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "box",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Box id as in the return's `boxes[].id`: a Ziffer such as `303` (CH) or a Kennzahl id such as `kz81` (DE).",
              "examples": [
                "303"
              ],
              "title": "Box"
            },
            "description": "Box id as in the return's `boxes[].id`: a Ziffer such as `303` (CH) or a Kennzahl id such as `kz81` (DE)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/VatBoxLine"
                  },
                  "title": "Response Box Lines V1 Vat Returns  Return Id  Boxes  Box  Lines Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/vat-returns/{return_id}/discard": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Discard a draft VAT return",
        "description": "Discards a `draft` return, which stays listed with the status `discarded`; the period\ncan then be computed again. Discarding a correction puts the original back from\n`amending` to `final`. Takes no body. Answers 409 unless the return is a draft.",
        "operationId": "discard_v1_vat_returns__return_id__discard_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}/file": {
      "get": {
        "tags": [
          "vat returns"
        ],
        "summary": "Return File",
        "description": "Downloads the return in the requested `format`: `xml` is the eCH-0217 upload for the\nESTV portal, `csv` the ZM import for the BZStOnline-Portal, `html` and `pdf` are\nprintable (shown inline, marked with the status and as a correction where it is one) and\n`json` is the return itself. Works for a draft too. Answers 422 when the format does not\nfit the return: `xml` needs a Swiss VAT return with an amount payable and the entity's\nUID, `csv` a recapitulative statement with at least one and at most 1000 rows.",
        "operationId": "return_file_v1_vat_returns__return_id__file_get",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "enum": [
                "csv",
                "html",
                "json",
                "pdf",
                "xml"
              ],
              "type": "string",
              "description": "File format: `json` (the return as `GET /v1/vat-returns/{return_id}` gives it), `xml` (eCH-0217, Swiss VAT returns), `csv` (BZStOnline-Portal ZM import, recapitulative statements), or `html` / `pdf` (printable form).",
              "default": "json",
              "title": "Format"
            },
            "description": "File format: `json` (the return as `GET /v1/vat-returns/{return_id}` gives it), `xml` (eCH-0217, Swiss VAT returns), `csv` (BZStOnline-Portal ZM import, recapitulative statements), or `html` / `pdf` (printable form)."
          },
          {
            "name": "csv_version",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^\\d+\\.\\d+$",
              "description": "ZM CSV: the version the BZStOnline-Portal's import help shows.",
              "default": "1.0",
              "title": "Csv Version"
            },
            "description": "ZM CSV: the version the BZStOnline-Portal's import help shows."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "eCH-0217 XML (CH), BZSt ZM CSV (DE), printable HTML or PDF, JSON.",
            "content": {
              "application/xml": {
                "schema": {
                  "type": "string"
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                }
              },
              "text/html": {
                "schema": {
                  "type": "string"
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/vat-returns/{return_id}/finalize": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Finalise a VAT return",
        "description": "Finalises a draft: it is recomputed, and the settlement entry (source `vat`, clearing\nthe reported VAT to the settlement account) goes through the approval policy. The\nresponse's `settlement.policy` is the decision: when the entry is posted the return is\n`final` and the period's VAT postings are locked; when it needs a second person the\nreturn is `pending_approval` until the entry is approved or rejected (a rejection puts\nit back to `draft`). A return with nothing to settle, such as a recapitulative\nstatement, becomes final at once and `settlement` is null. Needs the approval policy\naction `finalize_vat_return` (403 when denied, which is the default for agents). Answers\n409 when the return is not a draft, the ledger changed since it was computed, it has\nerror issues, or the VAT accounts hold amounts it does not explain and no `explanation`\nis given; 422 when `posting_date` is before the period's end or no open period follows.",
        "operationId": "finalize_v1_vat_returns__return_id__finalize_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatFinalizeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatFinalizeOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}/payment-candidates": {
      "get": {
        "tags": [
          "vat returns"
        ],
        "summary": "List the entries that may have paid a VAT return",
        "description": "Posted entries of the return's company, dated on or after the settlement, with a line on\nthe settlement account on the side opposite the settlement (a debit for VAT to pay, a credit\nfor a refund) that no return has linked yet; VAT settlements are left out. Typically the bank\nentry made by matching the bank debit to the settlement account on the bank worksheet. Empty\nfor a return that is not final or settled nothing.",
        "operationId": "payment_candidates_v1_vat_returns__return_id__payment_candidates_get",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/VatPaymentCandidate"
                  },
                  "title": "Response Payment Candidates V1 Vat Returns  Return Id  Payment Candidates Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/vat-returns/{return_id}/payments": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Link the entry that paid a VAT return",
        "description": "Links a posted entry as paying the return's VAT (or receiving its refund): its amount is\nwhat it puts on the settlement account against the settlement and its day the payment day.\nA part payment is one link of several; the return is `paid` once the links cover\n`settled_amount`, and a difference is shown (`payment_difference`), not refused. Answers 409\nunless the return is final and recorded as submitted, when it settled nothing, or when the\nentry already pays a return; 422 for an entry of another company, not posted, a VAT\nsettlement, dated before the settlement, or without a line on the settlement account on the\npaying side.\nA person's act: needs the approval policy action `finalize_vat_return`, which agents are\nalways denied (403).",
        "operationId": "link_payment_v1_vat_returns__return_id__payments_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatPaymentInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}/payments/{payment_id}/unlink": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Unlink a payment from a VAT return",
        "description": "Undoes a payment link made by mistake, with the `reason` (kept in the history; the link\nis not deleted and the entry stays posted). 404 for a link that is not in force on this\nreturn.\nA person's act: needs the approval policy action `finalize_vat_return`, which agents are\nalways denied (403).",
        "operationId": "unlink_payment_v1_vat_returns__return_id__payments__payment_id__unlink_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "payment_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the payment link (`payments[].id` of the return).",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Payment Id"
            },
            "description": "Id of the payment link (`payments[].id` of the return)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}/recompute": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Recompute a draft VAT return",
        "description": "Recomputes a draft from the current ledger, replacing its stored result and box\nlines. Send `adjustments` to replace the hand-entered amounts, or omit them to keep\nthe current ones. Answers 409 unless the return is a draft and 422 for an adjustment on\na box the ledger fills or computes, or one that changes the amount payable without an\noffset account.",
        "operationId": "recompute_v1_vat_returns__return_id__recompute_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatRecomputeInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}/submitted": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Record that a VAT return was submitted",
        "description": "Records that a `final` return (or one being amended) was submitted to the tax\nadministration (ESTV, Finanzamt, HMRC) on `submitted_on`, with the administration's reference\nif one was given, and who recorded it. Nothing is sent: the application files no return\nelectronically, and in a test copy (`test_copy`) the record is local only. From then on the\nperiod counts as filed (`due_status` `filed`) and the reminders of its due date stop. Answers\n409 unless the return is final or amending, or when a submission is already recorded\n(withdraw it first); 422 for a day in the future or before the period ends.\nA person's act: needs the approval policy action `finalize_vat_return`, which agents are\nalways denied (403).",
        "operationId": "submitted_v1_vat_returns__return_id__submitted_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatSubmitInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/vat-returns/{return_id}/submitted/withdraw": {
      "post": {
        "tags": [
          "vat returns"
        ],
        "summary": "Withdraw the recorded submission of a VAT return",
        "description": "Withdraws a submission recorded by mistake, with the `reason` (kept in the history; the\nrecord is not deleted). The period is not filed any more until a submission is recorded\nagain. Answers 409 when no submission is recorded or payments are linked (unlink them\nfirst).\nA person's act: needs the approval policy action `finalize_vat_return`, which agents are\nalways denied (403).",
        "operationId": "withdraw_submitted_v1_vat_returns__return_id__submitted_withdraw_post",
        "parameters": [
          {
            "name": "return_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "VAT return id.",
              "examples": [
                "3fa85f64-5717-4562-b3fc-2c963f66afa6"
              ],
              "title": "Return Id"
            },
            "description": "VAT return id."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VatReasonInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VatReturnOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/warehouses": {
      "get": {
        "tags": [
          "inventory"
        ],
        "summary": "List warehouses",
        "description": "Where the entities keep stock, by entity and code, with how many items each holds.",
        "operationId": "list_warehouses_v1_warehouses_get",
        "parameters": [
          {
            "name": "entity",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only this entity's (code or id).",
              "examples": [
                "CH01"
              ],
              "title": "Entity"
            },
            "description": "Only this entity's (code or id)."
          },
          {
            "name": "active",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only active (or inactive) ones.",
              "title": "Active"
            },
            "description": "Only active (or inactive) ones."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WarehouseOut"
                  },
                  "title": "Response List Warehouses V1 Warehouses Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      },
      "post": {
        "tags": [
          "inventory"
        ],
        "summary": "Create a warehouse",
        "description": "A warehouse of an entity; its first one is its default. The entity's first warehouse also\nadds the inventory accounts its chart names (inventory, cost of goods sold, inventory\nadjustments, goods received not invoiced) when it lacks them, which needs the right to manage\naccounts (403 otherwise). 409 when the entity has a warehouse with the code. Nothing is\nposted. Needs an `Idempotency-Key`.",
        "operationId": "create_warehouse_v1_warehouses_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Required: a unique key (up to 200 characters) per logical write. A retry with the same key and body replays the stored response; the same key with a different body answers 409."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WarehouseInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "required"
      }
    },
    "/v1/warehouses/{warehouse_id}": {
      "patch": {
        "tags": [
          "inventory"
        ],
        "summary": "Change a warehouse",
        "description": "Rename it, change its address, make it the default or (in)activate it. 409 when\ndeactivating the default warehouse or one that holds stock. Audited with the previous\nvalues.",
        "operationId": "update_warehouse_v1_warehouses__warehouse_id__patch",
        "parameters": [
          {
            "name": "warehouse_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Id of the warehouse (`GET /v1/warehouses`).",
              "title": "Warehouse Id"
            },
            "description": "Id of the warehouse (`GET /v1/warehouses`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WarehouseUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WarehouseOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "draft"
            ]
          },
          {
            "apiKeyAuth": [
              "draft"
            ]
          }
        ],
        "x-required-scope": "draft",
        "x-idempotency": "none"
      }
    },
    "/v1/webhook-deliveries/{delivery_id}/send-again": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Send a delivery again",
        "description": "Send a delivery (failed, delivered or waiting) again now, with the full round of retries;\nthe receiver sees the same event id. 409 `webhook_endpoint_disabled` while its endpoint is\nstopped. Audited.",
        "operationId": "send_delivery_again_v1_webhook_deliveries__delivery_id__send_again_post",
        "parameters": [
          {
            "name": "delivery_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The delivery's id (from the delivery log).",
              "title": "Delivery Id"
            },
            "description": "The delivery's id (from the delivery log)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/webhooks": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "List webhooks",
        "description": "The organization's webhook endpoints, the oldest first, with how many deliveries wait.\nNever the secret.",
        "operationId": "list_webhooks_v1_webhooks_get",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EndpointOut"
                  },
                  "title": "Response List Webhooks V1 Webhooks Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Add a webhook",
        "description": "Tell another system of events: from now on each event it subscribed to is sent to `url`\n(a POST of JSON), signed with the secret in this answer (`secret`, shown only here: keep it in\nthe receiving system). Any 2xx answer within 10 seconds delivers it; anything else is tried\nagain after 1, 5 and 30 minutes, then 2, 5, 10 and 24 hours, and then waits in the log to be\nsent again. A receiver may get an event twice (same `id`) and in any order. Needs the admin\nscope and a person (403 `webhook_person_only` for an agent); 422 `webhook_url_refused` for a\nURL that is not `https://` or not a public address; 409 `webhook_limit` beyond 20 endpoints.\nAudited without the secret.",
        "operationId": "create_webhook_v1_webhooks_post",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndpointInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/webhooks/event-types": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "List the events webhooks send",
        "description": "Every event an endpoint can subscribe to. Each message is a JSON object: `id` (the\nevent's id, also the `webhook-id` header), `type`, `timestamp`, `organization`, `entity` (the\ncompany's code), `test_copy` and `data` (the record's identifiers and figures; amounts as\nstrings). It is signed as Standard Webhooks specifies (`webhook-id`, `webhook-timestamp`,\n`webhook-signature`: `v1,` and the base64 HMAC-SHA256 of `id.timestamp.body` with the bytes of\nthe secret after `whsec_`).",
        "operationId": "list_event_types_v1_webhooks_event_types_get",
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "items": {
                    "$ref": "#/components/schemas/EventTypeOut"
                  },
                  "type": "array",
                  "title": "Response List Event Types V1 Webhooks Event Types Get"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "read"
            ]
          },
          {
            "apiKeyAuth": [
              "read"
            ]
          }
        ],
        "x-required-scope": "read"
      }
    },
    "/v1/webhooks/{endpoint_id}": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "Get a webhook",
        "description": "One endpoint, as the list shows it: its events, state, failures in a row and how many\ndeliveries wait. Never the secret.",
        "operationId": "get_webhook_v1_webhooks__endpoint_id__get",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The endpoint's id (`GET /v1/webhooks`).",
              "title": "Endpoint Id"
            },
            "description": "The endpoint's id (`GET /v1/webhooks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      },
      "patch": {
        "tags": [
          "webhooks"
        ],
        "summary": "Change a webhook",
        "description": "Change the URL, description or events, or stop (`disabled`) and start (`active`) it.\nStarted again, what waited goes out at once. Audited.",
        "operationId": "update_webhook_v1_webhooks__endpoint_id__patch",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The endpoint's id (`GET /v1/webhooks`).",
              "title": "Endpoint Id"
            },
            "description": "The endpoint's id (`GET /v1/webhooks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EndpointUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      },
      "delete": {
        "tags": [
          "webhooks"
        ],
        "summary": "Delete a webhook",
        "description": "Delete the endpoint with its delivery log; what waited is not sent. Audited.",
        "operationId": "delete_webhook_v1_webhooks__endpoint_id__delete",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The endpoint's id (`GET /v1/webhooks`).",
              "title": "Endpoint Id"
            },
            "description": "The endpoint's id (`GET /v1/webhooks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "204": {
            "description": "Successful Response"
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/webhooks/{endpoint_id}/deliveries": {
      "get": {
        "tags": [
          "webhooks"
        ],
        "summary": "List a webhook's deliveries",
        "description": "The delivery log: each event sent to the endpoint, the newest first, with its state, every\nattempt (when, the HTTP status or the error, how long) and the message.",
        "operationId": "list_deliveries_v1_webhooks__endpoint_id__deliveries_get",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The endpoint's id (`GET /v1/webhooks`).",
              "title": "Endpoint Id"
            },
            "description": "The endpoint's id (`GET /v1/webhooks`)."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "enum": [
                    "failed",
                    "pending",
                    "succeeded"
                  ],
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Only those in this state.",
              "title": "Status"
            },
            "description": "Only those in this state."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "maximum": 200,
              "minimum": 1,
              "description": "Most returned, the newest first.",
              "default": 50,
              "title": "Limit"
            },
            "description": "Most returned, the newest first."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/DeliveryOut"
                  },
                  "title": "Response List Deliveries V1 Webhooks  Endpoint Id  Deliveries Get"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin"
      }
    },
    "/v1/webhooks/{endpoint_id}/rotate-secret": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Give a webhook a new secret",
        "description": "A new signing secret (in this answer only); every attempt from now on is signed with it,\nthe old one no longer. Audited.",
        "operationId": "rotate_webhook_secret_v1_webhooks__endpoint_id__rotate_secret_post",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The endpoint's id (`GET /v1/webhooks`).",
              "title": "Endpoint Id"
            },
            "description": "The endpoint's id (`GET /v1/webhooks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    },
    "/v1/webhooks/{endpoint_id}/test": {
      "post": {
        "tags": [
          "webhooks"
        ],
        "summary": "Send a test event",
        "description": "Send a `webhook.test` event now and return what the endpoint answered (one attempt, kept\nin the log; never tried again). Also to a stopped endpoint, to check it before starting it.",
        "operationId": "test_webhook_v1_webhooks__endpoint_id__test_post",
        "parameters": [
          {
            "name": "endpoint_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The endpoint's id (`GET /v1/webhooks`).",
              "title": "Endpoint Id"
            },
            "description": "The endpoint's id (`GET /v1/webhooks`)."
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "Idempotency-Key"
            },
            "description": "Not used by this operation (it is safe to repeat, or guarded by state)."
          },
          {
            "name": "X-Request-Id",
            "in": "header",
            "required": false,
            "schema": {
              "anyOf": [
                {
                  "type": "string",
                  "maxLength": 200
                },
                {
                  "type": "null"
                }
              ],
              "title": "X-Request-Id"
            },
            "description": "Optional correlation id (up to 200 characters), stored with audit events; generated when absent."
          }
        ],
        "responses": {
          "200": {
            "description": "Successful Response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryOut"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed: the error envelope (`validation_failed`). For a malformed body or parameter its message is in sentences (\"Line 2: the quantity must be above zero\") and `fields` lists each error with pydantic's `loc`, `type` and `msg` beside its sentence (`message`) and its parts, to word it in another language: `items` (`name` and `number` from 1: line 2), `field` (its name as sent) and the `rule` it breaks with its `limit`, `count` and `choices` (none for a validator's own sentence); FastAPI's own `detail` list stays beside the envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key (`unauthorized`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "The caller lacks the required scope (`missing_right`, with `scope`), the key belongs to no person where a person is needed (`forbidden`), or the approval policy denies the action (`policy_denied`, with `action` and `rule_id`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "The resource does not exist, or belongs to another organization (`not_found`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "The request conflicts with the data: an `Idempotency-Key` reused with a different request, a closed period, or an integrity rule of the database (`conflict`, `integrity_violation`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "security": [
          {
            "bearerAuth": [
              "admin"
            ]
          },
          {
            "apiKeyAuth": [
              "admin"
            ]
          }
        ],
        "x-required-scope": "admin",
        "x-idempotency": "none"
      }
    }
  },
  "components": {
    "schemas": {
      "AcceptInput": {
        "properties": {
          "accepted_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accepted On",
            "description": "The day the customer accepted, within the quote's validity and not after today; default today. It is the day of the order."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's purchase order number, if any."
          }
        },
        "type": "object",
        "title": "AcceptInput",
        "examples": [
          {},
          {
            "accepted_on": "2026-10-20",
            "customer_reference": "PO-4711"
          }
        ]
      },
      "AccessLogEntry": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id",
            "description": "Sequence number of the entry; increases with time."
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "title": "At",
            "description": "When the request was made (ISO 8601, UTC)."
          },
          "user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Id",
            "description": "The auditor's user id."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The auditor's sign-in address."
          },
          "via": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Via",
            "description": "The app the auditor connected over MCP that made the request (e.g. `Claude (connected app)`); null for the auditor's own session."
          },
          "method": {
            "type": "string",
            "title": "Method",
            "description": "`GET` for a read or a download, `MCP` for a tool their app called; any other method asked to change something."
          },
          "path": {
            "type": "string",
            "title": "Path",
            "description": "What was opened, e.g. `/v1/entities/CH01/trial-balance`, or the tool's name, e.g. `trial_balance`."
          },
          "query": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Query",
            "description": "The query string of the request, or the tool's arguments as JSON; null for none."
          },
          "status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "The answer's HTTP status: 2xx served, 403 refused (for example a change an auditor may not make)."
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Address",
            "description": "The client address the request came from."
          },
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Request Id",
            "description": "The request's id, as in the audit trail."
          }
        },
        "type": "object",
        "required": [
          "id",
          "at",
          "user_id",
          "email",
          "via",
          "method",
          "path",
          "query",
          "status",
          "address",
          "request_id"
        ],
        "title": "AccessLogEntry",
        "description": "One request an external auditor made."
      },
      "AccountBalance": {
        "properties": {
          "account_id": {
            "type": "string",
            "format": "uuid",
            "title": "Account Id",
            "description": "Id (uuid) of the account."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Account code, e.g. `6500`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "`asset`, `liability`, `equity`, `revenue` or `expense`."
          },
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The statement line the account is grouped under, e.g. `pl.opex.other`."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Total debits posted to the account in the range, in the entity's functional currency."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Total credits posted to the account in the range, in the entity's functional currency. In a report in another currency, debit and credit hold the translated balance on its side, the other side 0."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "Debit minus credit for assets and expenses, credit minus debit for the others, so a normal balance is positive; in the report's currency."
          },
          "comparative": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Comparative"
              },
              {
                "type": "null"
              }
            ],
            "description": "Asked for with `compare`: the account's balance in the comparative report (the same range a year earlier, or the balance sheet at the comparative date) and the change; null when not asked for."
          },
          "budget": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Comparative"
              },
              {
                "type": "null"
              }
            ],
            "description": "Asked for with `budget=true` (income statement only): the account's amount in the approved budget and the variance; null when not asked for or without a budget."
          }
        },
        "type": "object",
        "required": [
          "account_id",
          "code",
          "name",
          "type",
          "report_line",
          "debit",
          "credit",
          "balance"
        ],
        "title": "AccountBalance"
      },
      "AccountChange": {
        "properties": {
          "account": {
            "$ref": "#/components/schemas/AccountOut",
            "description": "The account as it is now. While a change waits for a second person it is unchanged."
          },
          "status": {
            "type": "string",
            "enum": [
              "applied",
              "pending_approval"
            ],
            "title": "Status",
            "description": "`applied` (the account has changed, or nothing needed to change) or `pending_approval` (a second person decides; `approval_id`)."
          },
          "changed": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Changed",
            "description": "The fields that changed (`name`, `role`, `report_line`, `active`, `vat_recovery_percent`); with `pending_approval`, the ones that will change once approved."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request of a change that waits for a second person; decide it with `POST /v1/approvals/{approval_id}/approve` or `/reject`."
          }
        },
        "type": "object",
        "required": [
          "account",
          "status",
          "changed"
        ],
        "title": "AccountChange"
      },
      "AccountInput": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Account number, unique in the entity, e.g. `6510`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name, e.g. `Telefon und Internet`."
          },
          "type": {
            "type": "string",
            "enum": [
              "asset",
              "equity",
              "expense",
              "liability",
              "revenue"
            ],
            "title": "Type",
            "description": "`asset`, `liability`, `equity`, `revenue` or `expense`; decides the normal balance side and which report it appears in."
          },
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "Where the account appears in the statements, as a dotted key such as `pl.opex.other`, `pl.revenue` or `bs.assets.current.cash`. Use a line the chart already uses for the same type: each line holds one type of account (422 otherwise)."
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "The purpose the services use the account for, e.g. `bank`, `ar_control`, `vat_input`, `default_expense`; null for an ordinary account."
          },
          "control": {
            "type": "boolean",
            "title": "Control",
            "description": "True for a control account, which takes postings only from its subledger (receivables, payables, bank, fixed assets); default false.",
            "default": false
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code when the account only accepts one currency, e.g. `EUR`; null (default) accepts any."
          },
          "vat_recovery_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,2}0*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Recovery Percent",
            "description": "How much of the input VAT of a bill line booked to the account the company may deduct, in percent (0 to 100), when the line states none (ADR-0079): e.g. `0` on an account for gifts whose VAT the law excludes, `50` for a car used half privately. The rest of the VAT is booked as part of the cost on this account. Null: all of it."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "type",
          "report_line"
        ],
        "title": "AccountInput",
        "examples": [
          {
            "code": "6510",
            "name": "Telefon und Internet",
            "report_line": "pl.opex.other",
            "type": "expense"
          }
        ]
      },
      "AccountOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the account."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Account number, unique in the entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The account's name, the one the company keeps its books under; what official documents and filings print. Clients show it in their reader's language."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "`asset`, `liability`, `equity`, `revenue` or `expense`."
          },
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The statement line the account is grouped under, e.g. `pl.opex.other`."
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "The purpose the services use the account for, e.g. `bank`; null for an ordinary account."
          },
          "is_control": {
            "type": "boolean",
            "title": "Is Control",
            "description": "True for a control account, which only its subledger posts to."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The only currency the account accepts (ISO 4217); null accepts any."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "False for an account that no longer accepts postings."
          },
          "vat_recovery_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Recovery Percent",
            "description": "How much of the input VAT of a bill line booked to the account the company may deduct, in percent (0 to 100), when the line states none (ADR-0079): e.g. `0` on an account for gifts whose VAT the law excludes, `50` for a car used half privately. The rest of the VAT is booked as part of the cost on this account. Null: all of it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "type",
          "report_line",
          "role",
          "is_control",
          "currency",
          "active"
        ],
        "title": "AccountOut"
      },
      "AccountUpdate": {
        "properties": {
          "role": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 64,
                "pattern": "^[a-z][a-z0-9_]*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "The purpose the services use the account for, e.g. `retained_earnings` or `deferred_tax_asset` (`GET /v1/entities/{entity}/accounts` shows the roles in use). Send `null` to take the role away; omit to leave it. The role must be one the services know and fit the account's type (422), and no other account of the entity may hold it (409). A control role is refused (409) on an account that already has postings from outside its subledger. Changing a control or required role needs a second person: the answer is `202` with a pending approval."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "A new name for the account, e.g. `Telefon und Internet`; the number, type and postings stay as they are. Omit to leave it."
          },
          "report_line": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120,
                "pattern": "^(bs|pl)(\\.[a-z0-9_]+)+$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Report Line",
            "description": "The statement line the account is grouped under, e.g. `pl.opex.other`; each line holds one type of account, so an expense account goes on an expense line, never on a revenue or balance-sheet one (422). Omit to leave it."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "False stops postings to the account, true allows them again. Refused (409, naming why) while the account holds a role, is a control account, carries a balance (a P&L account: a result in a year not closed to zero), is named by unfinished work (an entry, invoice, bill, order, payment or recurring invoice), or while an asset, product, subscription, contract, party or setting posts to it. Omit to leave it."
          },
          "vat_recovery_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,2}0*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Recovery Percent",
            "description": "How much of the input VAT of a bill line booked to the account the company may deduct, in percent (0 to 100), when the line states none (ADR-0079): e.g. `0` on an account for gifts whose VAT the law excludes, `50` for a car used half privately. The rest of the VAT is booked as part of the cost on this account. Null: all of it. Send `null` to take it away; omit to leave it. Bills already entered keep theirs."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why; kept in the audit trail and shown to the second person who decides a change of a control or required role."
          }
        },
        "type": "object",
        "title": "AccountUpdate",
        "description": "Changes to an account of the chart. Only the fields sent change; send `role: null` to\ntake a role away. The number, type and currency of an account are fixed.",
        "examples": [
          {
            "reason": "Customer chart: 2979 holds the year's result",
            "role": "annual_result"
          }
        ]
      },
      "Acquisition": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The subsidiary."
          },
          "parent": {
            "type": "string",
            "title": "Parent",
            "description": "The parent that holds the investment."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The subsidiary's functional currency."
          },
          "ownership_percent": {
            "type": "string",
            "title": "Ownership Percent",
            "description": "The parent's share, in percent."
          },
          "nci_percent": {
            "type": "string",
            "title": "Nci Percent",
            "description": "The non-controlling share: 100 less it."
          },
          "nci_measurement": {
            "type": "string",
            "const": "proportionate_share",
            "title": "Nci Measurement",
            "description": "How the non-controlling interest is measured at acquisition: its proportionate share of the identifiable net assets (IFRS 3.19(b); section 307 HGB)."
          },
          "fair_value_basis": {
            "type": "string",
            "const": "book_value",
            "title": "Fair Value Basis",
            "description": "The identifiable net assets at acquisition are taken at the book value the member version states as their fair value (IFRS 3.18); no purchase price allocation."
          },
          "acquired_on": {
            "type": "string",
            "format": "date",
            "title": "Acquired On",
            "description": "The acquisition date."
          },
          "policy": {
            "type": "string",
            "title": "Policy",
            "description": "The goodwill policy."
          },
          "goodwill_years": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Goodwill Years",
            "description": "The useful life of goodwill (for `amortise`, and for the theoretical capitalisation of `offset_equity`)."
          },
          "investment_account": {
            "type": "string",
            "title": "Investment Account",
            "description": "The parent's account eliminated."
          },
          "consideration": {
            "type": "string",
            "title": "Consideration",
            "description": "The consideration, in the reporting currency."
          },
          "net_assets_local": {
            "type": "string",
            "title": "Net Assets Local",
            "description": "The subsidiary's net assets at acquisition in its currency."
          },
          "historical_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Historical Rate",
            "description": "The rate of the acquisition date; null without translation."
          },
          "closing_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closing Rate",
            "description": "The closing rate; null without translation."
          },
          "equity_at_acquisition": {
            "type": "string",
            "title": "Equity At Acquisition",
            "description": "The equity at acquisition in the reporting currency, at the historical rate."
          },
          "nci_at_acquisition": {
            "type": "string",
            "title": "Nci At Acquisition",
            "description": "The non-controlling interest at acquisition."
          },
          "goodwill_at_acquisition": {
            "type": "string",
            "title": "Goodwill At Acquisition",
            "description": "Consideration + non-controlling interest - net assets (IFRS 3.32); negative for a bargain purchase."
          },
          "goodwill_treatment": {
            "type": "string",
            "enum": [
              "asset",
              "bargain_purchase",
              "negative_goodwill",
              "none",
              "offset_equity"
            ],
            "title": "Goodwill Treatment",
            "description": "`asset` (kept in the subsidiary's currency at the closing rate, IAS 21.47, DRS 23.137), `offset_equity` (FER, a positive or negative difference), `bargain_purchase` (a gain, IFRS 3.34), `negative_goodwill` (a liability: released over five years under FER, kept after equity under HGB) or `none`."
          },
          "goodwill_local": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Goodwill Local",
            "description": "Goodwill in the subsidiary's currency."
          },
          "goodwill_closing": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Goodwill Closing",
            "description": "Goodwill at the closing rate (before amortisation)."
          },
          "goodwill_translation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Goodwill Translation",
            "description": "Goodwill at closing less at acquisition: to the owners' translation reserve."
          },
          "bargain_purchase_gain": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bargain Purchase Gain",
            "description": "The gain, if any."
          },
          "amortisation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Amortisation"
              },
              {
                "type": "null"
              }
            ],
            "description": "E7, for `amortise`."
          },
          "theoretical_capitalisation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TheoreticalCapitalisation"
              },
              {
                "type": "null"
              }
            ],
            "description": "For goodwill offset against equity with a useful life (FER): what a capitalisation would have given."
          },
          "negative_goodwill": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/NegativeGoodwill"
              },
              {
                "type": "null"
              }
            ],
            "description": "A negative difference kept as a liability, if any."
          },
          "net_assets_closing": {
            "type": "string",
            "title": "Net Assets Closing",
            "description": "The subsidiary's translated net assets at the group date."
          },
          "profit_of_year": {
            "type": "string",
            "title": "Profit Of Year",
            "description": "Its translated profit of the group year."
          },
          "nci_profit": {
            "type": "string",
            "title": "Nci Profit",
            "description": "The non-controlling interests' share of it."
          },
          "owners_profit": {
            "type": "string",
            "title": "Owners Profit",
            "description": "The owners' share of it."
          },
          "reserve": {
            "type": "string",
            "title": "Reserve",
            "description": "Its translation reserve."
          },
          "nci_reserve": {
            "type": "string",
            "title": "Nci Reserve",
            "description": "The non-controlling interests' share of it."
          },
          "other_equity": {
            "type": "string",
            "title": "Other Equity",
            "description": "Its other equity movements since the acquisition (earlier years' results, capital, dividends), translated."
          },
          "nci_other": {
            "type": "string",
            "title": "Nci Other",
            "description": "The non-controlling interests' share of them."
          },
          "nci_closing": {
            "type": "string",
            "title": "Nci Closing",
            "description": "The non-controlling interest at the group date: the sum of the four shares."
          },
          "nci_exact": {
            "type": "string",
            "title": "Nci Exact",
            "description": "The non-controlling share of the translated net assets, rounded once."
          },
          "nci_rounding": {
            "type": "string",
            "title": "Nci Rounding",
            "description": "`nci_closing` less `nci_exact`: the rounding of the parts, a cent or two."
          },
          "sources": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Sources",
            "description": "Per rule the paragraphs it is computed by."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/EliminationLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines of E4, E5 and E7 for this subsidiary."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "parent",
          "currency",
          "ownership_percent",
          "nci_percent",
          "nci_measurement",
          "fair_value_basis",
          "acquired_on",
          "policy",
          "goodwill_years",
          "investment_account",
          "consideration",
          "net_assets_local",
          "historical_rate",
          "closing_rate",
          "equity_at_acquisition",
          "nci_at_acquisition",
          "goodwill_at_acquisition",
          "goodwill_treatment",
          "net_assets_closing",
          "profit_of_year",
          "nci_profit",
          "owners_profit",
          "reserve",
          "nci_reserve",
          "other_equity",
          "nci_other",
          "nci_closing",
          "nci_exact",
          "nci_rounding",
          "sources"
        ],
        "title": "Acquisition",
        "description": "The basis of the capital consolidation of one subsidiary: every figure its lines rest on."
      },
      "ActivateInput": {
        "properties": {
          "credit_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Account",
            "description": "The account the initial direct costs and prepaid payments are taken from (where they were booked, e.g. prepayments); needed only when there are any."
          }
        },
        "type": "object",
        "title": "ActivateInput",
        "examples": [
          {
            "credit_account": "1500"
          }
        ]
      },
      "ActivationOut": {
        "properties": {
          "contract": {
            "$ref": "#/components/schemas/RevenueContractOut",
            "description": "The contract after the request."
          },
          "decision": {
            "type": "string",
            "enum": [
              "allow",
              "require_approval"
            ],
            "title": "Decision",
            "description": "`allow`: active now; `require_approval`: a second person decides (`POST /v1/approvals/{approval_id}/approve`)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request, when one is open."
          }
        },
        "type": "object",
        "required": [
          "contract",
          "decision",
          "approval_id"
        ],
        "title": "ActivationOut"
      },
      "ActivityCurrency": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the amounts."
          },
          "opening": {
            "type": "string",
            "title": "Opening",
            "description": "What we owed at the start of the first day."
          },
          "increases": {
            "type": "string",
            "title": "Increases",
            "description": "The sum of the positive movements."
          },
          "decreases": {
            "type": "string",
            "title": "Decreases",
            "description": "The sum of the negative movements (a negative amount)."
          },
          "closing": {
            "type": "string",
            "title": "Closing",
            "description": "What we owed at the end of the last day: `opening + increases + decreases`. Compare it with the closing balance of the statement the vendor sent."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ActivityLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The movements, oldest first."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "opening",
          "increases",
          "decreases",
          "closing",
          "lines"
        ],
        "title": "ActivityCurrency",
        "description": "The movements of one currency, from the opening to the closing balance."
      },
      "ActivityInput": {
        "properties": {
          "opportunity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Id",
            "description": "The deal it is about (`GET /v1/opportunities`)."
          },
          "lead_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lead Id",
            "description": "The lead it is about, before they are a customer (`GET /v1/leads`); then name no deal, entity, customer or contact."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code (or id) of the entity, for an activity about a customer only (one about a deal is in the deal's entity)."
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the customer, for an activity about a customer only (one about a deal names the deal's customer)."
          },
          "kind": {
            "type": "string",
            "enum": [
              "call",
              "email",
              "meeting",
              "note",
              "task"
            ],
            "title": "Kind",
            "description": "`note`, `call`, `meeting`, `email` or `task`."
          },
          "subject": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Subject",
            "description": "What it was or is."
          },
          "body": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 5000
              },
              {
                "type": "null"
              }
            ],
            "title": "Body",
            "description": "The details."
          },
          "occurred_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Occurred On",
            "description": "When it happened (a task: when it was set); omitted: today."
          },
          "due_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due On",
            "description": "A task: when it is due."
          },
          "assignee_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assignee User Id",
            "description": "A task: who does it (`GET /v1/people`); omitted: the deal's or the lead's owner."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who did it, or set the task (`GET /v1/people`); omitted: you (a key or an agent: the person behind it). It never changes."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "The person at the customer it was with (`GET /v1/contacts?party_id=`); omitted for an activity of a deal: the deal's contact."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "subject"
        ],
        "title": "ActivityInput",
        "examples": [
          {
            "body": "25 users, budget approved for Q1",
            "kind": "call",
            "occurred_on": "2026-10-04",
            "opportunity_id": "3f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c",
            "subject": "Discovery call"
          },
          {
            "assignee_user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
            "due_on": "2026-11-15",
            "entity": "CH01",
            "kind": "task",
            "party": "C-CH",
            "subject": "Send the renewal offer"
          }
        ]
      },
      "ActivityLine": {
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The day it was booked."
          },
          "kind": {
            "type": "string",
            "enum": [
              "application",
              "credit_note",
              "invoice",
              "other",
              "payment",
              "payment_reversal",
              "write_off"
            ],
            "title": "Kind",
            "description": "`invoice` (the vendor's bill), `credit_note`, `payment` (what we paid, or a refund received), `payment_reversal`, `application` (an amount on account or a credit note applied to a bill later, ADR-0045: one line off the payment or credit note, one on the bill), `write_off` (a customer invoice written off as uncollectable), or `other` (an opening balance or a manual entry)."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "Our number: the bill's, the payment's or the entry's."
          },
          "their_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Their Reference",
            "description": "The vendor's own number of the bill or credit note, to find it on the vendor's statement."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The bill or credit note it concerns."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Our number of that bill or credit note (for a payment: the one it settles)."
          },
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "The journal entry that booked it."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "In the currency of the block: positive when it raises what we owe (a bill), negative when it lowers it (a payment, a credit note)."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "What we owe after it: the running balance."
          }
        },
        "type": "object",
        "required": [
          "day",
          "kind",
          "reference",
          "their_reference",
          "document_id",
          "document_number",
          "entry_id",
          "amount",
          "balance"
        ],
        "title": "ActivityLine",
        "description": "One movement on the vendor's account: a bill, a credit note, a payment."
      },
      "ActivityOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Activity id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "opportunity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Id",
            "description": "The deal it is about."
          },
          "opportunity_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Number",
            "description": "The deal's number."
          },
          "party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Id",
            "description": "The customer it is about."
          },
          "party_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Code",
            "description": "The customer's code."
          },
          "lead_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lead Id",
            "description": "The lead it is about."
          },
          "lead_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lead Number",
            "description": "The lead's number."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "The person it was with."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Their name; `\"\"` once the contact is erased."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`note`, `call`, `meeting`, `email`, `task` or `stage_change` (written by a stage change of the deal)."
          },
          "subject": {
            "type": "string",
            "title": "Subject",
            "description": "What it was or is."
          },
          "body": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Body",
            "description": "The details."
          },
          "occurred_on": {
            "type": "string",
            "format": "date",
            "title": "Occurred On",
            "description": "When it happened."
          },
          "due_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due On",
            "description": "A task: when it is due."
          },
          "assignee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "A task: who does it."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who did it, or set the task; null for what an agent, a key or the system recorded without a person behind it."
          },
          "done_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Done At",
            "description": "A task: when it was done (UTC)."
          },
          "done_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Done By",
            "description": "A task: who did it."
          },
          "overdue": {
            "type": "boolean",
            "title": "Overdue",
            "description": "A task not done whose due day has passed (today where the entity is)."
          },
          "source": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "google_calendar",
                  "google_mail"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where an e-mail or meeting logged from a linked mailbox came from (`GET /v1/me/mailbox`); null for what a person or the system recorded."
          },
          "external_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Url",
            "description": "Where to open that e-mail or meeting (Gmail, Google Calendar)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it (whose mailbox, if captured)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "opportunity_id",
          "opportunity_number",
          "party_id",
          "party_code",
          "kind",
          "subject",
          "body",
          "occurred_on",
          "due_on",
          "assignee",
          "done_at",
          "done_by",
          "overdue",
          "created_by",
          "created_at"
        ],
        "title": "ActivityOut",
        "examples": [
          {
            "body": "25 users, budget approved for Q1",
            "created_at": "2026-10-04T08:10:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "entity": "CH01",
            "id": "4a7b8c9d-0e1f-4a2b-9c3d-4e5f6a7b8c9d",
            "kind": "call",
            "occurred_on": "2026-10-04",
            "opportunity_id": "3f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c",
            "opportunity_number": "OPP-000001",
            "overdue": false,
            "subject": "Discovery call"
          }
        ]
      },
      "ActivityRow": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "Who: the actor id that recorded it (`user:<id>` for a person, an agent's or a key's id otherwise), `total`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Their name as recorded."
          },
          "person": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "The person, when it is a user of the org."
          },
          "agent": {
            "type": "boolean",
            "title": "Agent",
            "description": "True for an AI agent."
          },
          "calls": {
            "type": "integer",
            "title": "Calls",
            "description": "Calls logged."
          },
          "meetings": {
            "type": "integer",
            "title": "Meetings",
            "description": "Meetings logged."
          },
          "emails": {
            "type": "integer",
            "title": "Emails",
            "description": "E-mails logged."
          },
          "notes": {
            "type": "integer",
            "title": "Notes",
            "description": "Notes logged."
          },
          "tasks_set": {
            "type": "integer",
            "title": "Tasks Set",
            "description": "Tasks set."
          },
          "tasks_done": {
            "type": "integer",
            "title": "Tasks Done",
            "description": "Tasks they marked done in the range."
          },
          "stage_changes": {
            "type": "integer",
            "title": "Stage Changes",
            "description": "Deals they moved to another stage."
          },
          "open_tasks": {
            "type": "integer",
            "title": "Open Tasks",
            "description": "Tasks assigned to them and not done, today."
          },
          "overdue_tasks": {
            "type": "integer",
            "title": "Overdue Tasks",
            "description": "Of them, past their due day."
          }
        },
        "type": "object",
        "required": [
          "key",
          "name",
          "person",
          "agent",
          "calls",
          "meetings",
          "emails",
          "notes",
          "tasks_set",
          "tasks_done",
          "stage_changes",
          "open_tasks",
          "overdue_tasks"
        ],
        "title": "ActivityRow"
      },
      "Address": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Max. 70 characters."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street or P.O. box, max. 70."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Max. 16."
          },
          "postal_code": {
            "type": "string",
            "title": "Postal Code",
            "description": "Without country prefix, max. 16."
          },
          "town": {
            "type": "string",
            "title": "Town",
            "description": "Max. 35."
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Z]{2}$",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2."
          }
        },
        "type": "object",
        "required": [
          "name",
          "postal_code",
          "town",
          "country"
        ],
        "title": "Address",
        "description": "A structured address (address type S)."
      },
      "AddressOut": {
        "properties": {
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "The street, without the number."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "The building number."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "The postal code."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "The town (the locality, or the postal town)."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "The canton or state as an ISO 3166-2 code (`CH-ZH`, `US-CA`) where the address forms pick it from a list (CH, DE, AT, US, CA); else null."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "The country, ISO 3166-1 alpha-2."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "The whole address as Google writes it."
          }
        },
        "type": "object",
        "required": [
          "street",
          "building_number",
          "postal_code",
          "town",
          "subdivision",
          "country",
          "text"
        ],
        "title": "AddressOut"
      },
      "AddressSuggestion": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "What `GET /v1/addresses/details` takes to fill the address."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "The whole address as it is suggested."
          },
          "main": {
            "type": "string",
            "title": "Main",
            "description": "Its first part: the street and number, or the place."
          },
          "secondary": {
            "type": "string",
            "title": "Secondary",
            "description": "The rest: postal code, town, country."
          }
        },
        "type": "object",
        "required": [
          "id",
          "text",
          "main",
          "secondary"
        ],
        "title": "AddressSuggestion"
      },
      "AddressSuggestionsOut": {
        "properties": {
          "available": {
            "type": "boolean",
            "title": "Available",
            "description": "Whether addresses are suggested on this server: false while it has no key for Google's Places API (then `suggestions` is always empty, and the postal code still gives the town)."
          },
          "suggestions": {
            "items": {
              "$ref": "#/components/schemas/AddressSuggestion"
            },
            "type": "array",
            "title": "Suggestions",
            "description": "At most five addresses that match the text, best first."
          }
        },
        "type": "object",
        "required": [
          "available",
          "suggestions"
        ],
        "title": "AddressSuggestionsOut"
      },
      "AdjustmentInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity."
          },
          "posting_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Date",
            "description": "The day the stock changes; omitted: today. Its period is open."
          },
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why: shown on the posting and its entry."
          },
          "offset_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Offset Account",
            "description": "The account the value is booked against (code or id); omitted: the inventory adjustment account (role `inventory_adjustment`). Opening stock names the opening balance clearing account."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/AdjustmentLine"
            },
            "type": "array",
            "maxItems": 500,
            "minItems": 1,
            "title": "Lines",
            "description": "The items."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "reason",
          "lines"
        ],
        "title": "AdjustmentInput",
        "examples": [
          {
            "entity": "CH01",
            "lines": [
              {
                "item": "SCANNER",
                "quantity": "-2"
              }
            ],
            "posting_date": "2026-08-31",
            "reason": "Two scanners damaged in the warehouse"
          },
          {
            "entity": "CH01",
            "lines": [
              {
                "item": "SCANNER",
                "quantity": "40",
                "unit_cost": "180.00"
              }
            ],
            "offset_account": "2298",
            "posting_date": "2026-08-01",
            "reason": "Opening stock from the old system"
          }
        ]
      },
      "AdjustmentLine": {
        "properties": {
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code (or id) of the stock item."
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "Warehouse code (or id); omitted: the default warehouse."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Quantity",
            "description": "What comes in (positive) or goes out (negative). A quantity in the item's unit, up to six decimals, e.g. `12` or `2.5`."
          },
          "unit_cost": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Cost",
            "description": "Of goods coming in: the cost of one unit in the functional currency; omitted: the moving average (needed when nothing is in stock). Goods going out always leave at the moving average."
          }
        },
        "type": "object",
        "required": [
          "item",
          "quantity"
        ],
        "title": "AdjustmentLine"
      },
      "AdminInvite": {
        "properties": {
          "email": {
            "type": "string",
            "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
            "title": "Email",
            "description": "The administrator's address; they sign in with the Google account of it, or, without one, with the address and a password."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Display name."
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "AdminInvite",
        "examples": [
          {
            "email": "petra.muster@example.com",
            "name": "Petra Muster"
          }
        ]
      },
      "AdminInvited": {
        "properties": {
          "user": {
            "$ref": "#/components/schemas/ProvisionedUser",
            "description": "The administrator, as invited."
          },
          "result": {
            "type": "string",
            "enum": [
              "already_invited",
              "invited"
            ],
            "title": "Result",
            "description": "`invited`: the person was just added. `already_invited`: they were invited before and have not signed in yet; nothing changed, and the act is recorded."
          },
          "sign_in_path": {
            "type": "string",
            "title": "Sign In Path",
            "description": "Where they sign in, on the host that serves the API (`/app/`)."
          },
          "password_email_sent": {
            "type": "boolean",
            "title": "Password Email Sent",
            "description": "True when Google e-mailed them the link that sets a password (a fresh one for someone invited before); false when password sign-in is not configured, or for an address of a Google Workspace domain, whose people sign in with Google.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "user",
          "result",
          "sign_in_path"
        ],
        "title": "AdminInvited"
      },
      "Aging": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "side": {
            "type": "string",
            "enum": [
              "payables",
              "receivables"
            ],
            "title": "Side",
            "description": "`receivables` or `payables`."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day the report is as of."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/AgingItem"
            },
            "type": "array",
            "title": "Items",
            "description": "Open documents, oldest due date first."
          },
          "totals_by_currency": {
            "additionalProperties": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "type": "object",
            "title": "Totals By Currency",
            "description": "Per currency, the open amount per bucket and `total`."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The entity's functional currency, for `totals_functional`.",
            "default": ""
          },
          "totals_functional": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Totals Functional",
            "description": "The open amount per bucket and `total` in the entity's functional currency: the sum of the items' `open_functional`, the carrying amounts the ledger holds. These are the figures the analytics aging trend shows for the same day."
          },
          "reconciliation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AgingReconciliation"
              },
              {
                "type": "null"
              }
            ],
            "description": "The aging against the ledger's control account as of `as_of`, so the difference is named: revaluation postings that sit on the control account."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "side",
          "as_of",
          "items",
          "totals_by_currency"
        ],
        "title": "Aging"
      },
      "AgingItem": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the document."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Document number."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "Document kind."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer or vendor."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer or vendor.",
            "default": ""
          },
          "party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Id",
            "description": "Id of the customer or vendor."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Document date."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the amounts."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Gross total, negative for a credit note."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "Open amount, negative for a credit note."
          },
          "open_functional": {
            "type": "string",
            "title": "Open Functional",
            "description": "The carrying amount the ledger holds for the document in the entity's functional currency: its booked total less the carrying amounts of the posted payments and credit notes (each as booked), so it ties to the FX revaluation. A pending allocation reserves `open` but relieves nothing yet. Negative for a credit note.",
            "default": "0.00"
          },
          "reserved": {
            "type": "boolean",
            "title": "Reserved",
            "description": "True when payments waiting for approval reserve the whole open amount: `open` is zero (nothing is left to pay), but the ledger still carries the document, so it is listed with its `open_functional` and its bucket.",
            "default": false
          },
          "days_overdue": {
            "type": "integer",
            "title": "Days Overdue",
            "description": "Days past the due date at `as_of`; 0 when not yet due."
          },
          "bucket": {
            "type": "string",
            "title": "Bucket",
            "description": "`current`, `1-30`, `31-60`, `61-90` or `90+` days overdue."
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number",
            "description": "The vendor's invoice number (bills)."
          },
          "cash_discount_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Date",
            "description": "Last day the cash discount may be taken."
          },
          "cash_discount": {
            "type": "string",
            "title": "Cash Discount",
            "description": "May still be taken on as_of.",
            "default": "0.00"
          },
          "payment_blocked": {
            "type": "boolean",
            "title": "Payment Blocked",
            "description": "A bill blocked for payment until a second person approves its variance against its purchase order.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "kind",
          "party",
          "document_date",
          "due_date",
          "currency",
          "total",
          "open",
          "days_overdue",
          "bucket"
        ],
        "title": "AgingItem"
      },
      "AgingReconciliation": {
        "properties": {
          "control_account": {
            "type": "string",
            "title": "Control Account",
            "description": "Code of the receivables or payables control account."
          },
          "group_control_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Group Control Account",
            "description": "Code of the group account (`ic_ar_control` or `ic_ap_control`) the documents of the entity's group entities post to, when it has one: the aging lists those documents with the others, so the balance it ties to is that of both accounts together."
          },
          "control_balance": {
            "type": "string",
            "title": "Control Balance",
            "description": "The control account's balance in the ledger as of `as_of`, in the functional currency, in its normal direction (what is owed to us, or by us)."
          },
          "totals_functional": {
            "type": "string",
            "title": "Totals Functional",
            "description": "The aging's total in the functional currency (`totals_functional.total`)."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`control_balance` less `totals_functional`."
          },
          "unrealised_fx": {
            "type": "string",
            "title": "Unrealised Fx",
            "description": "Entries of source `fx` (period-end revaluations) on the control account up to `as_of` that no reversal has cancelled yet: they sit on the control account but on no document."
          },
          "pending_settlements": {
            "type": "string",
            "title": "Pending Settlements",
            "description": "A memo: the functional amount of payments and applications waiting for approval on the listed items (an application on both of its items). They reserve the open amount in the document currency but are not booked, so they are in neither `control_balance` nor `totals_functional` and explain no part of the difference."
          },
          "unexplained": {
            "type": "string",
            "title": "Unexplained",
            "description": "`difference` less `unrealised_fx`: zero when the aging ties to the ledger; anything else is a posting on the control account that no document carries."
          }
        },
        "type": "object",
        "required": [
          "control_account",
          "control_balance",
          "totals_functional",
          "difference",
          "unrealised_fx",
          "pending_settlements",
          "unexplained"
        ],
        "title": "AgingReconciliation"
      },
      "AllocationInput-Input": {
        "properties": {
          "document": {
            "type": "string",
            "title": "Document",
            "description": "Document id or number."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Paid amount applied to the document, in the payment currency."
          },
          "document_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Amount",
            "description": "What the allocation settles on the document, in the document's currency (cash discount not included). Only for a document in another currency than the payment, e.g. a CHF receipt for a EUR invoice: give the EUR amount it settles, such as the open amount when the customer meant to pay the invoice in full. Default: `amount` converted at the payment date's rate. The difference between what the document carried and what the bank received is booked as realised FX gain or loss."
          },
          "discount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Discount",
            "description": "Cash discount (Skonto) taken on top of the amount, in the document's currency: the document is settled by its amount + discount. Only on invoices and bills with cash discount terms, until their cash discount date.",
            "default": "0"
          }
        },
        "type": "object",
        "required": [
          "document",
          "amount"
        ],
        "title": "AllocationInput"
      },
      "AllocationInput-Output": {
        "properties": {
          "document": {
            "type": "string",
            "title": "Document",
            "description": "Document id or number."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Paid amount applied to the document, in the payment currency."
          },
          "document_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Amount",
            "description": "What the allocation settles on the document, in the document's currency (cash discount not included). Only for a document in another currency than the payment, e.g. a CHF receipt for a EUR invoice: give the EUR amount it settles, such as the open amount when the customer meant to pay the invoice in full. Default: `amount` converted at the payment date's rate. The difference between what the document carried and what the bank received is booked as realised FX gain or loss."
          },
          "discount": {
            "type": "string",
            "title": "Discount",
            "description": "Cash discount (Skonto) taken on top of the amount, in the document's currency: the document is settled by its amount + discount. Only on invoices and bills with cash discount terms, until their cash discount date.",
            "default": "0.00"
          }
        },
        "type": "object",
        "required": [
          "document",
          "amount"
        ],
        "title": "AllocationInput"
      },
      "AllocationOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the allocation."
          },
          "kind": {
            "type": "string",
            "enum": [
              "credit_note",
              "credited_document",
              "payment",
              "write_off"
            ],
            "title": "Kind",
            "description": "payment: a payment or receipt; credit_note: a credit note applied to this document; credited_document: the invoice or bill this credit note settles; write_off: a write-off of the invoice as uncollectable (dated `applied_on`)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`pending` (the payment waits for approval), `posted`, `rejected` or `reversed` (the payment was reversed: it settled the document from its date to the reversal's and settles nothing now)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount applied to the document, in the document currency."
          },
          "source_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Amount",
            "description": "The same settlement on the other side, in its own currency (`source_currency`): what the payment received or paid for it, or what the credit note (or the credited document) took. Null when that side is in this document's currency."
          },
          "source_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Currency",
            "description": "The currency of the payment, credit note or credited document, when it is not this document's."
          },
          "functional_amount": {
            "type": "string",
            "title": "Functional Amount",
            "description": "This document's carrying amount relieved, in the functional currency (on a credit note applied later, the credit note's own, which may differ from the document's it settled)."
          },
          "fx_difference": {
            "type": "string",
            "title": "Fx Difference",
            "description": "Share of the realised FX gain (positive) or loss (negative), in the functional currency."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the allocation was created (UTC)."
          },
          "payment_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Id",
            "description": "Payment allocations: id of the payment or receipt."
          },
          "payment_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Number",
            "description": "Payment allocations: its number, e.g. `PAY-2026-000001`."
          },
          "payment_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Date",
            "description": "Payment allocations: its date."
          },
          "payment_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Status",
            "description": "Payment allocations: its status."
          },
          "write_off_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Write Off Id",
            "description": "A write-off: its id."
          },
          "write_off_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Write Off Number",
            "description": "A write-off: its number."
          },
          "payment_journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Journal Entry Id",
            "description": "Payment allocations: its journal entry, once posted."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The credit note, or the credited document."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Number of the credit note or credited document."
          },
          "document_kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Kind",
            "description": "Kind of that document."
          },
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "Date of that document."
          },
          "applied_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Applied On",
            "description": "An application made later (ADR-0045): the day it took effect, not the payment's or credit note's own date."
          },
          "application_journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Application Journal Entry Id",
            "description": "An application made later: its own journal entry, once posted (the payment's entry booked the amount on account, not this settlement)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "status",
          "amount",
          "functional_amount",
          "fx_difference",
          "created_at"
        ],
        "title": "AllocationOut",
        "description": "What settled a document, or what a credit note settled."
      },
      "AllowanceCharge": {
        "properties": {
          "charge": {
            "type": "boolean",
            "title": "Charge",
            "description": "True for a charge (BG-21, BG-28), false for an allowance (BG-20, BG-27)."
          },
          "amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "BT-92 / BT-99 / BT-136 / BT-141"
          },
          "base_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Amount",
            "description": "BT-93 / BT-100"
          },
          "percent": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Percent",
            "description": "BT-94 / BT-101"
          },
          "vat_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Category",
            "description": "BT-95 / BT-102"
          },
          "vat_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Rate",
            "description": "BT-96 / BT-103"
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "BT-97 / BT-104 / BT-139 / BT-144"
          },
          "reason_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason Code",
            "description": "BT-98 / BT-105 / BT-140"
          }
        },
        "type": "object",
        "required": [
          "charge"
        ],
        "title": "AllowanceCharge",
        "description": "Document level (BG-20 / BG-21) or invoice line level (BG-27 / BG-28)."
      },
      "AllowanceItem": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Number of the invoice."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date of the invoice."
          },
          "days_overdue": {
            "type": "integer",
            "title": "Days Overdue",
            "description": "Days past the due date at the period end (0: not due)."
          },
          "bucket": {
            "type": "string",
            "enum": [
              "1-30",
              "31-60",
              "61-90",
              "90+",
              "current"
            ],
            "title": "Bucket",
            "description": "Its aging bucket at the period end."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the invoice."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "What is open on it at the period end, in its currency."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "What the allowance is taken on, in the functional currency: what the books carry for it, with or without VAT as the settings say."
          },
          "kind": {
            "type": "string",
            "enum": [
              "general",
              "specific"
            ],
            "title": "Kind",
            "description": "`specific`: the invoice is marked doubtful; `general`: the bucket's percent."
          },
          "percent": {
            "type": "string",
            "title": "Percent",
            "description": "The percent applied."
          },
          "allowance": {
            "type": "string",
            "title": "Allowance",
            "description": "The allowance it calls for, in the functional currency."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why it is doubtful, for a specific one."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "document_number",
          "party",
          "due_date",
          "days_overdue",
          "bucket",
          "currency",
          "open",
          "base",
          "kind",
          "percent",
          "allowance"
        ],
        "title": "AllowanceItem",
        "description": "One open invoice and the allowance it calls for."
      },
      "AllowanceProposal": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "period_id": {
            "type": "string",
            "format": "uuid",
            "title": "Period Id",
            "description": "The period."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `2026-09`."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The period end the receivables are taken at."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The functional currency of the amounts."
          },
          "include_vat": {
            "type": "boolean",
            "title": "Include Vat",
            "description": "Whether the base includes VAT."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/AllowanceItem"
            },
            "type": "array",
            "title": "Items",
            "description": "The open invoices, oldest due date first."
          },
          "buckets": {
            "items": {
              "$ref": "#/components/schemas/BucketTotal"
            },
            "type": "array",
            "title": "Buckets",
            "description": "The general allowance per aging bucket."
          },
          "specific": {
            "type": "string",
            "title": "Specific",
            "description": "The specific allowance on the doubtful invoices."
          },
          "general": {
            "type": "string",
            "title": "General",
            "description": "The general allowance on the others."
          },
          "target": {
            "type": "string",
            "title": "Target",
            "description": "The allowance needed: specific plus general."
          },
          "booked": {
            "type": "string",
            "title": "Booked",
            "description": "What the allowance account holds at the period end (posted entries)."
          },
          "adjustment": {
            "type": "string",
            "title": "Adjustment",
            "description": "What the run posts: positive raises the allowance (an expense), negative releases part of it; 0 posts nothing."
          },
          "allowance_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allowance Account",
            "description": "The allowance account (role `receivable_allowance`); none when the chart lacks it."
          },
          "expense_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expense Account",
            "description": "The account the change goes to (role `allowance_expense`, else `bad_debt_expense`)."
          },
          "run_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Run Id",
            "description": "The period's run when it was made (then nothing more is run)."
          },
          "run_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Run Status",
            "description": "Status of the run's entry: `posted`, `pending_approval`; none when not run or when it posted nothing."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "period_id",
          "period",
          "as_of",
          "currency",
          "include_vat",
          "items",
          "buckets",
          "specific",
          "general",
          "target",
          "booked",
          "adjustment",
          "allowance_account",
          "expense_account"
        ],
        "title": "AllowanceProposal",
        "description": "What the allowance should be at a period end, and the entry that brings the allowance\naccount there."
      },
      "AllowanceRunResult": {
        "properties": {
          "run_id": {
            "type": "string",
            "format": "uuid",
            "title": "Run Id",
            "description": "The run."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `2026-09`."
          },
          "target": {
            "type": "string",
            "title": "Target",
            "description": "The allowance needed at the period end."
          },
          "booked": {
            "type": "string",
            "title": "Booked",
            "description": "What the allowance account held before the run."
          },
          "adjustment": {
            "type": "string",
            "title": "Adjustment",
            "description": "What the run posted (0: nothing)."
          },
          "submit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "How the entry was submitted (the approval policy decides); none when nothing was posted."
          }
        },
        "type": "object",
        "required": [
          "run_id",
          "period",
          "target",
          "booked",
          "adjustment",
          "submit"
        ],
        "title": "AllowanceRunResult"
      },
      "AllowanceSettingsInput": {
        "properties": {
          "percents": {
            "items": {
              "$ref": "#/components/schemas/BucketPercent-Input"
            },
            "type": "array",
            "maxItems": 5,
            "minItems": 5,
            "title": "Percents",
            "description": "The general allowance in percent for each of the five aging buckets, each bucket once."
          },
          "include_vat": {
            "type": "boolean",
            "title": "Include Vat",
            "description": "Whether the percent is taken on the receivable with VAT (Swiss practice for the del credere) or on its amount without VAT (the VAT comes back when the loss is final, so German practice takes the net)."
          }
        },
        "type": "object",
        "required": [
          "percents",
          "include_vat"
        ],
        "title": "AllowanceSettingsInput",
        "examples": [
          {
            "include_vat": true,
            "percents": [
              {
                "bucket": "current",
                "percent": "0"
              },
              {
                "bucket": "1-30",
                "percent": "5"
              },
              {
                "bucket": "31-60",
                "percent": "5"
              },
              {
                "bucket": "61-90",
                "percent": "5"
              },
              {
                "bucket": "90+",
                "percent": "5"
              }
            ]
          }
        ]
      },
      "AllowanceSettingsOut": {
        "properties": {
          "percents": {
            "items": {
              "$ref": "#/components/schemas/BucketPercent-Output"
            },
            "type": "array",
            "maxItems": 5,
            "minItems": 5,
            "title": "Percents",
            "description": "The general allowance in percent for each of the five aging buckets, each bucket once."
          },
          "include_vat": {
            "type": "boolean",
            "title": "Include Vat",
            "description": "Whether the percent is taken on the receivable with VAT (Swiss practice for the del credere) or on its amount without VAT (the VAT comes back when the loss is final, so German practice takes the net)."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "default": {
            "type": "boolean",
            "title": "Default",
            "description": "True while the company has not set its own: these are the suggested ones (0 % for receivables not yet due, 5 % for overdue ones)."
          }
        },
        "type": "object",
        "required": [
          "percents",
          "include_vat",
          "entity",
          "default"
        ],
        "title": "AllowanceSettingsOut",
        "examples": [
          {
            "include_vat": true,
            "percents": [
              {
                "bucket": "current",
                "percent": "0"
              },
              {
                "bucket": "1-30",
                "percent": "5"
              },
              {
                "bucket": "31-60",
                "percent": "5"
              },
              {
                "bucket": "61-90",
                "percent": "5"
              },
              {
                "bucket": "90+",
                "percent": "5"
              }
            ]
          }
        ]
      },
      "AmendmentAmounts": {
        "properties": {
          "old_price": {
            "type": "string",
            "title": "Old Price",
            "description": "The term's revenue contract price before, net of VAT."
          },
          "new_price": {
            "type": "string",
            "title": "New Price",
            "description": "Its price after: what the customer pays for the term as amended (`renew`: what the next term costs, the next contract's price)."
          },
          "earned": {
            "type": "string",
            "title": "Earned",
            "description": "The part of the new price for the service through the last day, recognised month by month; the rest (a kept prepayment) is recognised on the last day."
          },
          "credit_total": {
            "type": "string",
            "title": "Credit Total",
            "description": "What the credit notes credit in all, net of VAT."
          },
          "credits": {
            "items": {
              "$ref": "#/components/schemas/AmendmentCredit"
            },
            "type": "array",
            "title": "Credits",
            "description": "A credit note per billed period."
          },
          "next_term_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Term Start",
            "description": "`renew`: the next term's first day."
          },
          "next_term_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Term End",
            "description": "`renew`: its last day."
          },
          "next_price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Price",
            "description": "`change`: what the new lines bill from the effective date to the term's end, net of VAT: the price of their revenue contract."
          },
          "first_period_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Period Start",
            "description": "`change`: the first day of the new lines' first billing period."
          },
          "first_period_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Period End",
            "description": "`change`: its last day."
          },
          "first_charge": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Charge",
            "description": "`change`: what that first period bills, net of VAT: the new lines for the rest of the period the change falls in (`old_price` less `new_price` is what the current lines no longer bill, `credit_total` of it credited on invoices already made)."
          }
        },
        "type": "object",
        "required": [
          "old_price",
          "new_price",
          "earned",
          "credit_total",
          "credits"
        ],
        "title": "AmendmentAmounts"
      },
      "AmendmentCredit": {
        "properties": {
          "period_start": {
            "type": "string",
            "format": "date",
            "title": "Period Start",
            "description": "The billed period credited: its first day."
          },
          "period_end": {
            "type": "string",
            "format": "date",
            "title": "Period End",
            "description": "Its last day."
          },
          "invoice_id": {
            "type": "string",
            "format": "uuid",
            "title": "Invoice Id",
            "description": "The period's invoice."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What is credited, net of VAT."
          }
        },
        "type": "object",
        "required": [
          "period_start",
          "period_end",
          "invoice_id",
          "amount"
        ],
        "title": "AmendmentCredit"
      },
      "AmendmentInput": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "cancel",
              "change",
              "renew"
            ],
            "title": "Kind",
            "description": "`cancel`: end the current term early, on `end_date`. `renew`: renew it into the next term (for a subscription whose terms do not renew it, `auto_renew` false). `change`: bill `lines` instead of the current lines from `effective_date` to the term's end (an upgrade or a downgrade).",
            "default": "cancel"
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "`cancel`: the last day of service, from the current term's first day to its last (its last day ends it at the term end without renewing)."
          },
          "proration": {
            "type": "string",
            "enum": [
              "none",
              "prorate"
            ],
            "title": "Proration",
            "description": "`cancel`: `prorate` credits the unused part of every period billed past `end_date` (a credit note per invoice); `none` keeps what was billed, a non-refundable prepayment, recognised as revenue on `end_date`.",
            "default": "prorate"
          },
          "effective_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Effective Date",
            "description": "`change`: the first day of the new lines, after the first day of the terms in force and at the latest the term's last day (today, the first day of the next billing period, or another day). Every period billed past the day before is credited for the part the new lines replace, and the first period of the new lines bills its days from this day."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/SubscriptionLineInput"
                },
                "type": "array",
                "maxItems": 50,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "`change`: every line from `effective_date` (a line that stays as it is is named again), each priced as given or at the product's list price in force that day, and with an SSP that day."
          },
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why, kept with the change."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "AmendmentInput",
        "examples": [
          {
            "end_date": "2026-06-20",
            "kind": "cancel",
            "proration": "prorate",
            "reason": "The customer closes its Zürich office"
          },
          {
            "effective_date": "2026-06-15",
            "kind": "change",
            "lines": [
              {
                "product": "PLATFORM",
                "quantity": "12"
              }
            ],
            "reason": "Two more seats for the new team"
          }
        ]
      },
      "AmendmentLineOut": {
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "The product."
          },
          "product_code": {
            "type": "string",
            "title": "Product Code",
            "description": "Its code."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What is sold."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "How many units."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net price of one unit per `price_period`."
          },
          "price_period": {
            "type": "string",
            "enum": [
              "month",
              "year"
            ],
            "title": "Price Period",
            "description": "`month` or `year`."
          },
          "discount_percent": {
            "type": "string",
            "title": "Discount Percent",
            "description": "Discount in percent."
          },
          "monthly_amount": {
            "type": "string",
            "title": "Monthly Amount",
            "description": "What a month of service costs."
          }
        },
        "type": "object",
        "required": [
          "product_id",
          "product_code",
          "description",
          "quantity",
          "unit_price",
          "price_period",
          "discount_percent",
          "monthly_amount"
        ],
        "title": "AmendmentLineOut"
      },
      "AmendmentOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Amendment id."
          },
          "subscription_id": {
            "type": "string",
            "format": "uuid",
            "title": "Subscription Id",
            "description": "The subscription."
          },
          "kind": {
            "type": "string",
            "enum": [
              "cancel",
              "change",
              "renew"
            ],
            "title": "Kind",
            "description": "What it changes."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "The last day of service of the term amended (`renew`: the term's last day)."
          },
          "effective_date": {
            "type": "string",
            "format": "date",
            "title": "Effective Date",
            "description": "The first day the change applies."
          },
          "proration": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "none",
                  "prorate"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Proration",
            "description": "`cancel`: `prorate` or `none`."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why."
          },
          "term_start": {
            "type": "string",
            "format": "date",
            "title": "Term Start",
            "description": "The first day of the term it amends."
          },
          "contract_id": {
            "type": "string",
            "format": "uuid",
            "title": "Contract Id",
            "description": "That term's revenue contract."
          },
          "amounts": {
            "$ref": "#/components/schemas/AmendmentAmounts",
            "description": "The amounts the second person approves."
          },
          "status": {
            "type": "string",
            "enum": [
              "applied",
              "pending_approval",
              "rejected"
            ],
            "title": "Status",
            "description": "`pending_approval` (a second person decides in `/v1/approvals`), `applied` or `rejected`."
          },
          "modification_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Modification Id",
            "description": "The modification of the revenue contract it made, once applied."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/AmendmentLineOut"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "`change`: the lines from `effective_date`."
          },
          "new_contract_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "New Contract Id",
            "description": "`change`: the revenue contract of the new lines, once applied."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved it."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who asked for it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When."
          }
        },
        "type": "object",
        "required": [
          "id",
          "subscription_id",
          "kind",
          "end_date",
          "effective_date",
          "proration",
          "reason",
          "term_start",
          "contract_id",
          "amounts",
          "status",
          "modification_id",
          "approved_by",
          "approved_at",
          "created_by",
          "created_at"
        ],
        "title": "AmendmentOut"
      },
      "AmendmentRequestOut": {
        "properties": {
          "amendment": {
            "$ref": "#/components/schemas/AmendmentOut",
            "description": "The amendment, waiting for approval."
          },
          "approval_id": {
            "type": "string",
            "format": "uuid",
            "title": "Approval Id",
            "description": "The approval request a second person decides (`POST /v1/approvals/{approval_id}/approve`)."
          },
          "subscription": {
            "$ref": "#/components/schemas/SubscriptionOut",
            "description": "The subscription, unchanged until then."
          }
        },
        "type": "object",
        "required": [
          "amendment",
          "approval_id",
          "subscription"
        ],
        "title": "AmendmentRequestOut"
      },
      "Amortisation": {
        "properties": {
          "months": {
            "type": "integer",
            "title": "Months",
            "description": "Months amortised up to the group date."
          },
          "of_months": {
            "type": "integer",
            "title": "Of Months",
            "description": "Months of the useful life."
          },
          "accumulated_local": {
            "type": "string",
            "title": "Accumulated Local",
            "description": "Accumulated amortisation in the subsidiary's currency."
          },
          "of_year_local": {
            "type": "string",
            "title": "Of Year Local",
            "description": "Of which in the group year."
          },
          "accumulated_closing": {
            "type": "string",
            "title": "Accumulated Closing",
            "description": "The accumulated amount at the closing rate, off the goodwill."
          }
        },
        "type": "object",
        "required": [
          "months",
          "of_months",
          "accumulated_local",
          "of_year_local",
          "accumulated_closing"
        ],
        "title": "Amortisation"
      },
      "Answer": {
        "properties": {
          "answer": {
            "type": "string",
            "title": "Answer",
            "description": "The answer in prose."
          },
          "citations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Citations",
            "description": "Entry and document numbers the tools returned."
          },
          "unverified_references": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unverified References",
            "description": "Numbers in the answer that no tool returned; treat with care."
          },
          "tool_calls": {
            "items": {
              "$ref": "#/components/schemas/ToolCall"
            },
            "type": "array",
            "title": "Tool Calls",
            "description": "The read-only tools the agent called to find the figures."
          }
        },
        "type": "object",
        "required": [
          "answer",
          "citations",
          "unverified_references",
          "tool_calls"
        ],
        "title": "Answer"
      },
      "AnswerInput": {
        "properties": {
          "answer": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 1,
            "title": "Answer",
            "description": "The person's answer."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "answer"
        ],
        "title": "AnswerInput",
        "examples": [
          {
            "answer": "A deposit from Zürich Kunde AG for order 17."
          }
        ]
      },
      "ApplicationInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity, e.g. `CH01`."
          },
          "payment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment",
            "description": "Id or number of a posted payment or receipt with an amount on account to apply. Give this or `credit_note`."
          },
          "credit_note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Note",
            "description": "Id or number of a posted credit note with an open amount to apply. Give this or `payment`."
          },
          "application_date": {
            "type": "string",
            "format": "date",
            "title": "Application Date",
            "description": "The day the application takes effect (ISO 8601): on or after the payment or credit note and every document it settles, in an open period. The aging and the statement count it from this day."
          },
          "allocations": {
            "items": {
              "$ref": "#/components/schemas/ApplyTo"
            },
            "type": "array",
            "minItems": 1,
            "title": "Allocations",
            "description": "The invoices or bills it settles, each an open posted document of the same customer or vendor, with the amount applied (and, for a document in another currency, what it settles there). Together at most what is left on account (or open on the credit note)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "application_date",
          "allocations"
        ],
        "title": "ApplicationInput",
        "examples": [
          {
            "allocations": [
              {
                "amount": "250.00",
                "document": "INV-2026-000012"
              }
            ],
            "application_date": "2026-10-10",
            "entity": "CH01",
            "payment": "RCPT-2026-000004"
          },
          {
            "allocations": [
              {
                "amount": "120.00",
                "document": "INV-2026-000015"
              }
            ],
            "application_date": "2026-10-10",
            "credit_note": "CN-2026-000003",
            "entity": "CH01"
          }
        ]
      },
      "ApplicationResult": {
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "credit_note",
              "payment"
            ],
            "title": "Source",
            "description": "What was applied: `payment` or `credit_note`."
          },
          "source_id": {
            "type": "string",
            "format": "uuid",
            "title": "Source Id",
            "description": "Id of the payment or credit note applied."
          },
          "allocations": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "title": "Allocations",
            "description": "Ids of the new allocations, one per document."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, or `pending_approval` when the approval policy needs a second person: until then the amounts are reserved, on both sides."
          },
          "fx_difference": {
            "type": "string",
            "title": "Fx Difference",
            "description": "Realised FX gain (positive) or loss (negative) booked, in the functional currency: the payment's or credit note's carrying amount against the documents'. 0 without a currency difference."
          },
          "left": {
            "type": "string",
            "title": "Left",
            "description": "What is left to apply afterwards, in its currency."
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "How the application's entry was submitted: `policy`, entry id and `approval_id`."
          }
        },
        "type": "object",
        "required": [
          "source",
          "source_id",
          "allocations",
          "status",
          "fx_difference",
          "left",
          "submit"
        ],
        "title": "ApplicationResult"
      },
      "Applied": {
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid",
            "title": "User Id",
            "description": "Id of the person whose access changed."
          },
          "done": {
            "type": "string",
            "title": "Done",
            "description": "What changed, in plain words."
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "done"
        ],
        "title": "Applied"
      },
      "ApplyTo": {
        "properties": {
          "document": {
            "type": "string",
            "title": "Document",
            "description": "Id or number of the invoice or bill to settle."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Amount applied to it, in the currency of the payment or credit note applied."
          },
          "document_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Amount",
            "description": "What it settles on the document, in the document's currency. Only for a document in another currency than the payment or credit note applied; default: `amount` converted at the application date's rate. The difference is booked as realised FX gain or loss."
          }
        },
        "type": "object",
        "required": [
          "document",
          "amount"
        ],
        "title": "ApplyTo"
      },
      "AppropriationInput": {
        "properties": {
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year whose closed result is appropriated."
          },
          "resolution_date": {
            "type": "string",
            "format": "date",
            "title": "Resolution Date",
            "description": "The date of the resolution, ISO 8601; the entry is dated then, in an open period (normally in the new year). A dividend is a liability only from this date."
          },
          "reference": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reference",
            "description": "The resolution or minutes it rests on."
          },
          "destinations": {
            "items": {
              "$ref": "#/components/schemas/Destination"
            },
            "type": "array",
            "minItems": 1,
            "title": "Destinations",
            "description": "Where the result goes. Their sum may not exceed what is left of the result; a partial appropriation leaves the rest visible."
          }
        },
        "type": "object",
        "required": [
          "fiscal_year",
          "resolution_date",
          "reference",
          "destinations"
        ],
        "title": "AppropriationInput",
        "examples": [
          {
            "destinations": [
              {
                "account": "2950",
                "amount": "3175.00",
                "kind": "legal_profit_reserve"
              },
              {
                "account": "2261",
                "amount": "30000.00",
                "kind": "dividend_payable"
              },
              {
                "amount": "30325.00",
                "kind": "retained_earnings"
              }
            ],
            "fiscal_year": 2026,
            "reference": "Minutes of the general meeting of 20 May 2027, item 3",
            "resolution_date": "2027-05-20"
          }
        ]
      },
      "AppropriationOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the appropriation."
          },
          "fiscal_year_close_id": {
            "type": "string",
            "format": "uuid",
            "title": "Fiscal Year Close Id",
            "description": "The year close it appropriates."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year whose result it appropriates."
          },
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "The journal entry (source `appropriation`)."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Its number."
          },
          "resolution_date": {
            "type": "string",
            "format": "date",
            "title": "Resolution Date",
            "description": "The date of the shareholders' resolution."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "The resolution or minutes it rests on."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Signed like the result of the year: positive for a profit appropriated, negative for a loss carried forward; the reversal of an appropriation has the opposite sign."
          },
          "reverses_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reverses Id",
            "description": "For a reversal, the appropriation it reverses; else null."
          },
          "reversed": {
            "type": "boolean",
            "title": "Reversed",
            "description": "True when a later reversal cancels this appropriation."
          },
          "destinations": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Destinations",
            "description": "Where it went: `kind`, `account` code and `amount`."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it, as an actor object."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was recorded (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "fiscal_year_close_id",
          "fiscal_year",
          "entry_id",
          "entry_number",
          "resolution_date",
          "reference",
          "amount",
          "reverses_id",
          "reversed",
          "destinations",
          "created_by",
          "created_at"
        ],
        "title": "AppropriationOut"
      },
      "AppropriationResult": {
        "properties": {
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "How the entry went through the approval policy (a second person approves it by default)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The signed amount appropriated, like the result."
          },
          "remainder_after": {
            "type": "string",
            "title": "Remainder After",
            "description": "What would be left of the result once this and every earlier appropriation is posted."
          },
          "withholding_tax": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Tax",
            "description": "For a Swiss entity with a dividend destination: the 35 % withholding tax the entry books as payable (dividends under the notification procedure excluded). Null otherwise."
          },
          "withholding_tax_due": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Tax Due",
            "description": "When the withholding tax (or the notification) is due: 30 days after the dividend falls due, taken as the resolution date (Art. 16 para. 1 lit. c VStG). Null without a Swiss dividend."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "Things to do by hand: the Swiss withholding tax on a dividend and the legal profit reserve."
          }
        },
        "type": "object",
        "required": [
          "submit",
          "amount",
          "remainder_after",
          "withholding_tax",
          "warnings"
        ],
        "title": "AppropriationResult"
      },
      "AppropriationReverseInput": {
        "properties": {
          "on": {
            "type": "string",
            "format": "date",
            "title": "On",
            "description": "The date of the reversing entry, in an open period."
          },
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why; kept in the audit trail."
          }
        },
        "type": "object",
        "required": [
          "on",
          "reason"
        ],
        "title": "AppropriationReverseInput",
        "examples": [
          {
            "on": "2027-06-30",
            "reason": "Resolution withdrawn"
          }
        ]
      },
      "ApprovalOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the approval request; the `{approval_id}` of the decision operations."
          },
          "object_type": {
            "type": "string",
            "title": "Object Type",
            "description": "What the request is about: `journal_entry` (a posting), `journal_reversal` (reversing a posted entry), `party`, `purchase_order`, `purchase_match`, `account_role`, `recurring_invoice` (the terms of a recurring invoice), `revenue_contract` or `subscription` (the terms of a contract or a subscription), `plan_version` (a submitted budget or forecast version)."
          },
          "object_id": {
            "type": "string",
            "format": "uuid",
            "title": "Object Id",
            "description": "Id (uuid) of that journal entry (for a reversal: the entry to reverse), party, purchase order, bill, account, recurring invoice, revenue contract, subscription or plan version; for `posting_limit`, the company (entity); for `approval_policy`, the organization."
          },
          "action": {
            "type": "string",
            "title": "Action",
            "description": "The action waiting for a decision: `post` for a journal entry; `reverse_entry` for a reversal; for a party `activate_party`, `change_bank_details`, `change_party_details` or `change_party_status`; `change_required_account_role` or `change_company_bank_details` (new bank details of the company) for an account; `activate_recurring_invoice` for a recurring invoice; `activate_revenue_contract` for a revenue contract; `approve_subscription` for a subscription; `approve_plan` for a plan version; `change_posting_limit` for raising or removing a company's posting approval limit; `change_approval_policy` for a change that relaxes the approval policy."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`pending`, `approved` or `rejected`; a request its requester withdrew is `rejected` with a `comment` starting with `withdrawn`, and `withdrawn` true."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who asked, as an actor object (`type`, `id`, `name`); that actor cannot decide the request."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why a decision is needed: the reason text of the policy rule."
          },
          "summary": {
            "additionalProperties": true,
            "type": "object",
            "title": "Summary",
            "description": "What is being asked, e.g. for an entry its description, entry date, amount and source; for an account its `account`, the `current` and `proposed` values and the `reason`. A subscription's request, its early end or renewal also carries `words` (what it is about), a `Reason` the screens word by its code (`approvals.request`); why a request waits, by code, is `reason_words`. The request to approve the invoice of an asset's sale carries `asset_sale`: the `asset`, the `entry_id` and `lines` (`account`, `name`, `debit`, `credit`) of the asset's entry its approval books too, and its `profit_or_loss` (a gain positive) in its `currency`."
          },
          "decided_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided By",
            "description": "Who decided, as an actor object; null while pending."
          },
          "decided_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided At",
            "description": "When it was decided (ISO 8601, UTC); null while pending."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "The comment given with the decision; null if none."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the request was made (ISO 8601, UTC)."
          },
          "withdrawn": {
            "type": "boolean",
            "title": "Withdrawn",
            "description": "True when the person who asked took the request back (whichever key or session): it is `rejected`, decided by her, with the comment `withdrawn` (and her words after `withdrawn: `). A rejection by a second person is false, whatever its comment says.",
            "default": false
          },
          "reason_words": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Reason"
              },
              {
                "type": "null"
              }
            ],
            "description": "`reason` by code (`approvals.why`) and the values it names, for the screens to word; null where the reason has English words only (a policy rule's own text)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "object_type",
          "object_id",
          "action",
          "status",
          "requested_by",
          "reason",
          "summary",
          "decided_by",
          "decided_at",
          "comment",
          "created_at"
        ],
        "title": "ApprovalOut"
      },
      "ApprovalPolicyOut": {
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "default",
              "organization"
            ],
            "title": "Source",
            "description": "default, or the organization's own table."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "0 until the organization first changes its policy."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When the current version was made (ISO 8601, UTC); null at version 0."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "The actor that made it, as an actor object; null at version 0."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "The comment given with the current version; null if none."
          },
          "actions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Actions",
            "description": "Every action the services ask the policy about."
          },
          "agents_always_denied": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Agents Always Denied",
            "description": "Actions no organization policy can allow agents."
          },
          "table": {
            "$ref": "#/components/schemas/PolicyTable",
            "description": "The decision table in force."
          },
          "pending_change": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PendingPolicyChange"
              },
              {
                "type": "null"
              }
            ],
            "description": "A change that relaxes the policy and waits for a second administrator; the table above stays in force until it is approved. Null if none."
          }
        },
        "type": "object",
        "required": [
          "source",
          "version",
          "updated_at",
          "updated_by",
          "comment",
          "actions",
          "agents_always_denied",
          "table"
        ],
        "title": "ApprovalPolicyOut"
      },
      "ApproverDeclaration": {
        "properties": {
          "person_name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 2,
            "title": "Person Name",
            "description": "The person's full name, as an auditor reads it."
          },
          "relationship": {
            "type": "string",
            "enum": [
              "board_member",
              "employee",
              "external_accountant",
              "other",
              "partner"
            ],
            "title": "Relationship",
            "description": "The person's relationship to the company: `external_accountant` (such as a Treuhänder), `board_member`, `partner` (a co-owner), `employee` or `other`."
          },
          "organisation": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Organisation",
            "description": "The person's firm, such as the accounting firm."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Anything else an auditor should know."
          },
          "confirmed": {
            "type": "boolean",
            "const": true,
            "title": "Confirmed",
            "description": "The administrator confirms that this is a different real person, not another account of their own, and that this declaration is recorded for the company's auditor."
          }
        },
        "type": "object",
        "required": [
          "person_name",
          "relationship",
          "confirmed"
        ],
        "title": "ApproverDeclaration",
        "description": "What the administrator who gives a person the right to approve declares about them.",
        "examples": [
          {
            "confirmed": true,
            "organisation": "Keller Treuhand AG",
            "person_name": "Anna Keller",
            "relationship": "external_accountant"
          }
        ]
      },
      "ApproverOut": {
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid",
            "title": "User Id",
            "description": "Id (uuid) of the user."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The person's sign-in address."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The person's display name."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`invited`, `active` or `disabled`."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The rights the person holds now."
          },
          "declaration": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Declaration",
            "description": "What was declared when the person got the right to approve (`person_name`, `relationship`, `organisation`, `note`); null for a person who got it before declarations or through the platform's provisioning."
          },
          "declared_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Declared By",
            "description": "The administrator who declared it (`type`, `id`, `name`)."
          },
          "declared_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Declared At",
            "description": "When it was declared."
          },
          "acknowledged_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acknowledged At",
            "description": "When the person confirmed that their approvals are recorded in their name; null until they do (they decide nothing before)."
          },
          "changes": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Changes",
            "description": "The changes of the person's access, oldest first: `action` (`user.invite`, `user.update`, `approver.declare`, `approver.acknowledge`), `at`, `by` and `data`."
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "email",
          "name",
          "status",
          "scopes",
          "declaration",
          "declared_by",
          "declared_at",
          "acknowledged_at",
          "changes"
        ],
        "title": "ApproverOut",
        "description": "One person who may approve, in the approver register."
      },
      "AreaOut": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "The area's key, as roles and `Me.areas` name it."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Its name, as the app's sidebar shows it."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "What lies in it, in plain words."
          }
        },
        "type": "object",
        "required": [
          "key",
          "title",
          "summary"
        ],
        "title": "AreaOut"
      },
      "AskRequest": {
        "properties": {
          "question": {
            "type": "string",
            "maxLength": 4000,
            "minLength": 3,
            "title": "Question",
            "description": "The question in plain language, 3 to 4000 characters, e.g. `What was the total of office expenses in September 2026?`."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Default entity for the question."
          }
        },
        "type": "object",
        "required": [
          "question"
        ],
        "title": "AskRequest",
        "examples": [
          {
            "entity": "CH01",
            "question": "What was the total of office expenses (account 6500) in September 2026?"
          }
        ]
      },
      "AssetBookInput": {
        "properties": {
          "book": {
            "type": "string",
            "title": "Book",
            "description": "Tax book code of the entity, e.g. 'TAX-CH'."
          },
          "asset_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asset Class",
            "description": "data-vNext asset class, e.g. 'ch.estv.it_hardware_software' or 'us.macrs.gds.5y'; fills method, life, rate and convention."
          },
          "method": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "declining_balance",
                  "straight_line",
                  "sum_of_years_digits"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Depreciation method: `straight_line`, `declining_balance` or `sum_of_years_digits`. Required when no `asset_class` is given; a class fills it."
          },
          "useful_life_years": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Useful Life Years",
            "description": "Useful life in years, a positive decimal string, e.g. \"5\"."
          },
          "rate_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Percent",
            "description": "Yearly rate in percent (above 0, up to 100), for declining balance. Omitted: from the asset class or the engine's default."
          },
          "convention": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "full_year",
                  "half_year",
                  "mid_month",
                  "pro_rata_months"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Convention",
            "description": "How the first and last year are prorated: `full_year`, `half_year`, `mid_month` or `pro_rata_months` (months in service). Omitted: from the asset class or the engine's default."
          },
          "periods": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Periods",
            "description": "Years to show. Omitted, a declining balance without a life ends with the asset's accounting schedule, what is left written off in its last year (a pooling regime such as UK capital allowances shows 30 years)."
          }
        },
        "type": "object",
        "required": [
          "book"
        ],
        "title": "AssetBookInput",
        "examples": [
          {
            "asset_class": "ch.estv.it_hardware_software",
            "book": "TAX-CH"
          }
        ]
      },
      "AssetBookOut": {
        "properties": {
          "book": {
            "type": "string",
            "title": "Book",
            "description": "Book code (`BOOK`, `MEMO` or a tax book code)."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Book name."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`book` or `tax`."
          },
          "standard": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Standard",
            "description": "The framework or tax regime of the book (or the memo's asset class)."
          },
          "posts_to_gl": {
            "type": "boolean",
            "title": "Posts To Gl",
            "description": "true only for the accounting book."
          },
          "deferred_tax": {
            "type": "boolean",
            "title": "Deferred Tax",
            "description": "true when this book carries deferred tax."
          },
          "asset_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asset Class",
            "description": "data-vNext asset class used for this book, if any."
          },
          "asset_class_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Asset Class Name",
            "description": "Name of the asset class in force on `as_of`, in the regime's own language (not translated); null when the book has no class, the class is unknown to data-vNext or no longer in force, or data-vNext cannot be reached."
          },
          "method": {
            "type": "string",
            "title": "Method",
            "description": "Depreciation method of the book's schedule."
          },
          "dataset_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dataset Version",
            "description": "Version of the data-vNext dataset that produced the schedule."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "Date of the position, ISO 8601."
          },
          "accumulated": {
            "type": "string",
            "title": "Accumulated",
            "description": "Accounting book: depreciation in the ledger. Tax book: scheduled to date."
          },
          "carrying_amount": {
            "type": "string",
            "title": "Carrying Amount",
            "description": "Cost less `accumulated` (the tax base for a tax book)."
          },
          "temporary_difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Temporary Difference",
            "description": "Tax books: accounting carrying amount less the tax base."
          },
          "tax_rate_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate Percent",
            "description": "Rate used for deferred tax, for the book that carries it."
          },
          "deferred_tax_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deferred Tax Amount",
            "description": "`temporary_difference` times the tax rate, for that book."
          },
          "schedule": {
            "items": {
              "$ref": "#/components/schemas/ScheduleYear"
            },
            "type": "array",
            "title": "Schedule",
            "description": "The schedule by fiscal year."
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "What the schedule says about itself, in English: where its parameters came from, how it ends, and each change of the asset's value that rebased it."
          },
          "note_reasons": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Note Reasons",
            "description": "`notes` by code, in the same order (`erp.contracts.words.SCHEDULE_NOTES`): the screens word each as `assets.scheduleNote.<code>` from its `details`."
          }
        },
        "type": "object",
        "required": [
          "book",
          "name",
          "kind",
          "standard",
          "posts_to_gl",
          "deferred_tax",
          "asset_class",
          "method",
          "dataset_version",
          "as_of",
          "accumulated",
          "carrying_amount",
          "schedule",
          "notes"
        ],
        "title": "AssetBookOut"
      },
      "AssetChangeOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the change."
          },
          "asset": {
            "type": "string",
            "title": "Asset",
            "description": "The asset's code."
          },
          "kind": {
            "type": "string",
            "enum": [
              "impairment",
              "impairment_reversal",
              "partial_retirement",
              "revaluation"
            ],
            "title": "Kind",
            "description": "`partial_retirement`, `impairment`, `impairment_reversal` or `revaluation`."
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "Day of the change, ISO 8601."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why, as given."
          },
          "retired_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Retired Percent",
            "description": "A partial retirement: the part of the cost retired, in percent."
          },
          "cost_before": {
            "type": "string",
            "title": "Cost Before",
            "description": "The asset's cost before the change."
          },
          "cost_after": {
            "type": "string",
            "title": "Cost After",
            "description": "Its cost after the change."
          },
          "carrying_before": {
            "type": "string",
            "title": "Carrying Before",
            "description": "The carrying amount before the change, after the depreciation to the end of the change's period (the entry books that depreciation first)."
          },
          "carrying_after": {
            "type": "string",
            "title": "Carrying After",
            "description": "The carrying amount after the change."
          },
          "depreciation_to_period_end": {
            "type": "string",
            "title": "Depreciation To Period End",
            "description": "The depreciation to the end of the change's period that the entry booked."
          },
          "proceeds": {
            "type": "string",
            "title": "Proceeds",
            "description": "A partial retirement: the net proceeds."
          },
          "profit_or_loss": {
            "type": "string",
            "title": "Profit Or Loss",
            "description": "What the change booked to profit or loss: a gain positive (a part sold above its carrying amount, an impairment reversed, a revaluation reversing an earlier loss), a loss negative."
          },
          "surplus_change": {
            "type": "string",
            "title": "Surplus Change",
            "description": "What it booked to the revaluation surplus in equity: an increase positive."
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "The change's journal entry: posted, or waiting for approval (the policy's decision); a rejection puts the asset back as it was."
          }
        },
        "type": "object",
        "required": [
          "id",
          "asset",
          "kind",
          "date",
          "reason",
          "retired_percent",
          "cost_before",
          "cost_after",
          "carrying_before",
          "carrying_after",
          "depreciation_to_period_end",
          "proceeds",
          "profit_or_loss",
          "surplus_change",
          "submit"
        ],
        "title": "AssetChangeOut"
      },
      "AssetEvent": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "When it happened (the entry date), ISO 8601."
          },
          "kind": {
            "type": "string",
            "enum": [
              "acquisition",
              "adjustment",
              "depreciation",
              "disposal",
              "impairment",
              "impairment_reversal",
              "partial_retirement",
              "revaluation",
              "reversal",
              "tax_depreciation"
            ],
            "title": "Kind",
            "description": "`acquisition` (its cost put on the books), `depreciation` (a period's run or a top-up), `partial_retirement` (a part sold or scrapped), `impairment`, `impairment_reversal`, `revaluation`, `disposal`, `reversal` (an entry that reverses one of these), `adjustment` (any other entry booked to the asset) or `tax_depreciation` (a tax book's depreciation of an ended fiscal year: tax books post nothing)."
          },
          "book": {
            "type": "string",
            "title": "Book",
            "description": "`BOOK` (the accounting book) or the tax book's code."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "The entry's text, or the tax book's name and year."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What it changed the asset's value in that book by, in the entity's functional currency: positive for an acquisition, negative for depreciation and a disposal."
          },
          "book_value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Book Value",
            "description": "The accounting book's value after it, counting posted entries only; null for an entry not posted (yet) and for a tax book."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "Status of the entry: `posted`, `pending_approval`, `rejected` or `draft`; null for a tax book's year."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "The journal entry (`GET /v1/journal-entries/{id}`); null when nothing was posted for it (a tax book, or cost already on the books when it was registered)."
          },
          "journal_entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Number",
            "description": "Its number, once posted."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The purchase bill an acquisition came from (`GET /v1/documents/{id}`)."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "That bill's number."
          }
        },
        "type": "object",
        "required": [
          "date",
          "kind",
          "book",
          "description",
          "amount",
          "book_value",
          "status",
          "journal_entry_id",
          "journal_entry_number",
          "document_id",
          "document_number"
        ],
        "title": "AssetEvent"
      },
      "AssetHistory": {
        "properties": {
          "asset": {
            "type": "string",
            "title": "Asset",
            "description": "Asset id (uuid)."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency of the amounts."
          },
          "events": {
            "items": {
              "$ref": "#/components/schemas/AssetEvent"
            },
            "type": "array",
            "title": "Events",
            "description": "Everything booked to the asset, oldest first: its acquisition, each depreciation, any other entry naming it, its disposal and reversals; and each tax book's depreciation of the fiscal years that have ended."
          },
          "changes": {
            "items": {
              "$ref": "#/components/schemas/AuditEventOut"
            },
            "type": "array",
            "title": "Changes",
            "description": "The asset's audit trail, newest first, as `GET /v1/audit-events` gives it (registration, a tax book added)."
          }
        },
        "type": "object",
        "required": [
          "asset",
          "currency",
          "events",
          "changes"
        ],
        "title": "AssetHistory"
      },
      "AssetInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code (or id) that owns the asset, e.g. `CH01`."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Left out: the company's next asset number (`FA-00001`, counted without gaps). Give one (up to 40 characters, e.g. an asset tag) only to keep it; unique in the entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Asset name or description, e.g. `Server rack`."
          },
          "acquisition_date": {
            "type": "string",
            "format": "date",
            "title": "Acquisition Date",
            "description": "Date the asset was acquired, ISO 8601 (YYYY-MM-DD)."
          },
          "in_service_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "In Service Date",
            "description": "Date depreciation starts, ISO 8601. Default: the acquisition date."
          },
          "cost": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Cost",
            "description": "Acquisition cost as a positive decimal string in the entity's functional currency, e.g. \"12000.00\"."
          },
          "salvage": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Salvage",
            "description": "Residual value at the end of the life, a decimal string, e.g. \"1000.00\". Default \"0\".",
            "default": "0"
          },
          "method": {
            "type": "string",
            "enum": [
              "declining_balance",
              "straight_line",
              "sum_of_years_digits"
            ],
            "title": "Method",
            "description": "Depreciation method: `straight_line`, `declining_balance` or `sum_of_years_digits`. Default `straight_line`.",
            "default": "straight_line"
          },
          "useful_life_years": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Useful Life Years",
            "description": "Useful life in years as a positive decimal string, e.g. \"5\"."
          },
          "rate_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Percent",
            "description": "Declining balance only: the yearly rate in percent (above 0, up to 100). Omitted: the double-declining rate."
          },
          "convention": {
            "type": "string",
            "enum": [
              "full_year",
              "half_year",
              "mid_month",
              "pro_rata_months"
            ],
            "title": "Convention",
            "description": "How the first and last year are prorated: `full_year`, `half_year`, `mid_month` or `pro_rata_months` (months in service). Default `pro_rata_months`.",
            "default": "pro_rata_months"
          },
          "tax_asset_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Asset Class",
            "description": "data-vNext tax asset class, e.g. 'de.afa.computer_hardware'."
          },
          "cost_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost Account",
            "description": "GL account code of the asset cost, e.g. `1500`. Default: the entity's fixed-asset cost account. An asset class with accounts of its own (Swiss KMU chart: IT hardware `1520` and `1529`) names both accounts; naming one without the other is refused."
          },
          "accumulated_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accumulated Account",
            "description": "GL account code of the accumulated depreciation, e.g. `1509`. Default: the entity's accumulated-depreciation account. Named together with `cost_account` or not at all."
          },
          "expense_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expense Account",
            "description": "GL account code of the depreciation expense. Default: the entity's depreciation-expense account."
          },
          "source_document": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Document",
            "description": "Purchase bill (id or number) that capitalised the cost."
          },
          "post_acquisition": {
            "type": "boolean",
            "title": "Post Acquisition",
            "description": "Post Dr asset cost / Cr credit_account (when not bought via a bill).",
            "default": false
          },
          "credit_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Account",
            "description": "GL account code credited by `post_acquisition`, e.g. `1020`. Required when `post_acquisition` is true."
          },
          "books": {
            "items": {
              "$ref": "#/components/schemas/AssetBookInput"
            },
            "type": "array",
            "title": "Books",
            "description": "Tax books to depreciate the asset in as well."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name",
          "acquisition_date",
          "cost",
          "useful_life_years"
        ],
        "title": "AssetInput",
        "examples": [
          {
            "acquisition_date": "2026-09-01",
            "code": "FA-001",
            "cost": "12000.00",
            "entity": "CH01",
            "name": "Server rack",
            "useful_life_years": "5"
          }
        ]
      },
      "AssetOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Asset id (uuid)."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Asset code, e.g. `FA-001`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Asset name."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the owning entity."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`active`, `disposed` (set once the disposal entry is posted) or `reversed` (its acquisition reversed, set once the reversal is posted)."
          },
          "acquisition_date": {
            "type": "string",
            "format": "date",
            "title": "Acquisition Date",
            "description": "Acquisition date, ISO 8601."
          },
          "in_service_date": {
            "type": "string",
            "format": "date",
            "title": "In Service Date",
            "description": "Date depreciation starts, ISO 8601."
          },
          "disposal_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disposal Date",
            "description": "Disposal date, ISO 8601; null while not disposed."
          },
          "cost": {
            "type": "string",
            "title": "Cost",
            "description": "Cost, a decimal string in the entity's functional currency: the acquisition cost, less what partial retirements took out, or the revalued amount after a revaluation."
          },
          "salvage": {
            "type": "string",
            "title": "Salvage",
            "description": "Residual value, a decimal string in the functional currency."
          },
          "method": {
            "type": "string",
            "title": "Method",
            "description": "`straight_line`, `declining_balance` or `sum_of_years_digits`."
          },
          "useful_life_years": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Useful Life Years",
            "description": "Useful life in years."
          },
          "rate_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Percent",
            "description": "Declining-balance rate in percent, when one was given."
          },
          "convention": {
            "type": "string",
            "title": "Convention",
            "description": "`full_year`, `half_year`, `mid_month` or `pro_rata_months`."
          },
          "cost_account": {
            "type": "string",
            "title": "Cost Account",
            "description": "GL account code of the cost."
          },
          "accumulated_account": {
            "type": "string",
            "title": "Accumulated Account",
            "description": "GL account code of the accumulated depreciation."
          },
          "expense_account": {
            "type": "string",
            "title": "Expense Account",
            "description": "GL account code of the depreciation expense."
          },
          "source_bill": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Bill",
            "description": "Number of the purchase bill that capitalised the cost, if linked."
          },
          "source_bill_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Bill Id",
            "description": "Id of that purchase bill (uuid), if linked."
          },
          "books": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Books",
            "description": "Codes of the books the asset is depreciated in, `BOOK` first."
          },
          "value_changes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Value Changes",
            "description": "The changes in value the asset can take now (`partial_retirement`, `impairment`, `impairment_reversal`, `revaluation`): the law of the company's books allows them (no reversal of an impairment under US GAAP or ASPE, whatever the chart; IFRS books allow it; no revaluation above cost under local laws that keep assets at cost), an impairment reversal only while something is left to reverse today (the cap the reversal checks, above zero). Empty once the asset is disposed of."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "entity",
          "status",
          "acquisition_date",
          "in_service_date",
          "disposal_date",
          "cost",
          "salvage",
          "method",
          "useful_life_years",
          "rate_percent",
          "convention",
          "cost_account",
          "accumulated_account",
          "expense_account",
          "source_bill",
          "source_bill_id",
          "books",
          "value_changes"
        ],
        "title": "AssetOut"
      },
      "AssetRegisterLine": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Asset id (uuid); opens the asset where its code is not unique."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Asset code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Asset name."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`active`, `disposed`, or `reversed` (its acquisition reversed: off the register, shown with 0)."
          },
          "in_service_date": {
            "type": "string",
            "format": "date",
            "title": "In Service Date",
            "description": "Date depreciation starts, ISO 8601."
          },
          "cost": {
            "type": "string",
            "title": "Cost",
            "description": "Acquisition cost in the entity's functional currency; 0 once the asset is disposed of on or before the report date (the ledger has derecognised it)."
          },
          "accumulated": {
            "type": "string",
            "title": "Accumulated",
            "description": "Accumulated depreciation in the ledger up to the report date; 0 once the asset is disposed of."
          },
          "net_book_value": {
            "type": "string",
            "title": "Net Book Value",
            "description": "`cost` less `accumulated`; 0 for a disposed asset."
          },
          "salvage": {
            "type": "string",
            "title": "Salvage",
            "description": "Residual value: an active asset whose net book value is down to it is fully depreciated."
          },
          "tax_asset_class": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Asset Class",
            "description": "Tax asset class of the tax memo, if any."
          },
          "source_bill": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Bill",
            "description": "Number of the purchase bill that capitalised the cost, if linked."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "status",
          "in_service_date",
          "cost",
          "accumulated",
          "net_book_value",
          "salvage",
          "tax_asset_class",
          "source_bill"
        ],
        "title": "AssetRegisterLine"
      },
      "AssetRegistered": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Asset id (uuid)."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Asset code."
          },
          "schedule": {
            "additionalProperties": true,
            "type": "object",
            "title": "Schedule",
            "description": "The depreciation schedule from data-vNext."
          },
          "tax_schedule": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Schedule",
            "description": "The tax memo schedule, when `tax_asset_class` was given."
          },
          "acquisition_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Status",
            "description": "With `post_acquisition`: the acquisition entry's status, `posted` or `pending_approval`; null when nothing was posted (e.g. bought via a bill)."
          },
          "acquisition_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Number",
            "description": "The acquisition entry's number once posted; else null."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "schedule"
        ],
        "title": "AssetRegistered"
      },
      "AssetReversalResult": {
        "properties": {
          "asset": {
            "type": "string",
            "title": "Asset",
            "description": "Asset code."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_approval",
              "reversed"
            ],
            "title": "Status",
            "description": "`reversed`: the acquisition is reversed and the asset is off the register; `pending_approval`: the reversal waits for a second person (`approval_id`) and the asset stays active until it is approved."
          },
          "reversal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversal Entry Id",
            "description": "The reversal entry once posted; null while it waits, and for an asset without an acquisition entry of its own (nothing to reverse: it leaves the register)."
          },
          "reversal_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversal Number",
            "description": "Its number, once posted."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request (`object_type` `journal_reversal`) while it waits."
          }
        },
        "type": "object",
        "required": [
          "asset",
          "status"
        ],
        "title": "AssetReversalResult"
      },
      "AssetSaleInput": {
        "properties": {
          "percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Percent",
            "description": "The part retired, in percent of the asset's cost (above 0, below 100)."
          },
          "cost": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost",
            "description": "The part retired as an amount of the asset's cost, in the company's currency (below the cost). Give this or `percent`."
          },
          "sale_date": {
            "type": "string",
            "format": "date",
            "title": "Sale Date",
            "description": "Day of the sale, ISO 8601: the invoice date and the date the asset (or the part) leaves. Its period must be open."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "The buying customer's code (or id)."
          },
          "net_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Net Amount",
            "description": "The selling price without VAT, in the invoice currency."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The invoice currency; default: the customer's currency."
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "exempt",
              "reduced",
              "standard",
              "zero"
            ],
            "title": "Rate Type",
            "description": "The VAT rate the sale carries, as for any invoice line of goods: `standard` (default; e.g. 8.1 % in Switzerland, 19 % in Germany), `reduced`, `zero` or `exempt`. The customer's country decides the treatment (export, intra-EU supply, reverse charge).",
            "default": "standard"
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "The invoice line's text; default: `Sale of <asset code> <asset name>`."
          }
        },
        "type": "object",
        "required": [
          "sale_date",
          "customer",
          "net_amount"
        ],
        "title": "AssetSaleInput",
        "examples": [
          {
            "customer": "C-CH",
            "net_amount": "8000.00",
            "sale_date": "2026-10-15"
          }
        ]
      },
      "AssetSaleOut": {
        "properties": {
          "invoice_id": {
            "type": "string",
            "format": "uuid",
            "title": "Invoice Id",
            "description": "The sales invoice (`GET /v1/documents/{id}`)."
          },
          "invoice_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Number",
            "description": "Its number, once posted."
          },
          "invoice_status": {
            "type": "string",
            "title": "Invoice Status",
            "description": "`posted` or `pending_approval`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The invoice currency."
          },
          "net_amount": {
            "type": "string",
            "title": "Net Amount",
            "description": "The invoice's net amount."
          },
          "tax_amount": {
            "type": "string",
            "title": "Tax Amount",
            "description": "Its VAT."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "What the customer owes."
          },
          "proceeds": {
            "type": "string",
            "title": "Proceeds",
            "description": "The net amount in the company's currency: what the asset (or the part) was sold for; the gain or loss is against it."
          },
          "disposal": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The whole asset sold: its disposal entry. Null for a part."
          },
          "change": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/AssetChangeOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "A part sold: the partial retirement."
          }
        },
        "type": "object",
        "required": [
          "invoice_id",
          "invoice_number",
          "invoice_status",
          "currency",
          "net_amount",
          "tax_amount",
          "total",
          "proceeds",
          "disposal",
          "change"
        ],
        "title": "AssetSaleOut"
      },
      "AssistantCard": {
        "properties": {
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "What the card is, by the feature module that made it, e.g. `report` (a list or report the assistant built, which one click saves)."
          },
          "title": {
            "type": "string",
            "maxLength": 200,
            "title": "Title",
            "description": "The card's title, in the person's language."
          },
          "data": {
            "additionalProperties": true,
            "type": "object",
            "title": "Data",
            "description": "What the module's screen shows, in the module's own shape (for `report`: `entity` and `definition`, the body of `POST /v1/entities/{entity}/saved-reports/run`)."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "title",
          "data"
        ],
        "title": "AssistantCard"
      },
      "AssistantReply": {
        "properties": {
          "reply": {
            "type": "string",
            "title": "Reply",
            "description": "The assistant's answer, in the language asked for."
          },
          "charts": {
            "items": {
              "$ref": "#/components/schemas/Chart"
            },
            "type": "array",
            "title": "Charts",
            "description": "Charts shown beside the answer."
          },
          "cards": {
            "items": {
              "$ref": "#/components/schemas/AssistantCard"
            },
            "type": "array",
            "title": "Cards",
            "description": "What the feature modules show beside the answer, e.g. a list the assistant built (`report`), which one click saves."
          },
          "close": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PeriodState"
              },
              {
                "type": "null"
              }
            ],
            "description": "With `period_id`: the period's close after this turn."
          },
          "tool_calls": {
            "items": {
              "$ref": "#/components/schemas/ToolCall"
            },
            "type": "array",
            "title": "Tool Calls",
            "description": "What the assistant looked at and did."
          },
          "model": {
            "type": "string",
            "title": "Model",
            "description": "The model that answered."
          }
        },
        "type": "object",
        "required": [
          "reply",
          "charts",
          "close",
          "tool_calls",
          "model"
        ],
        "title": "AssistantReply"
      },
      "AssistantRequest": {
        "properties": {
          "messages": {
            "items": {
              "$ref": "#/components/schemas/Message"
            },
            "type": "array",
            "maxItems": 40,
            "minItems": 1,
            "title": "Messages",
            "description": "The conversation so far, oldest first; the last message is the person's (at most 40, each up to 8000 characters, the last up to 4000)."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code of the company the person is working in, e.g. `CH01`; default: the organization's first."
          },
          "period_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period Id",
            "description": "Id (uuid) of a period to close with the person: the assistant works through its close, and the answer lists the person's open steps (`actions`)."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language the assistant answers in.",
            "default": "en"
          },
          "page": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 300,
                "pattern": "^/"
              },
              {
                "type": "null"
              }
            ],
            "title": "Page",
            "description": "The page of the app the person is on, e.g. `/cash-forecast`: the assistant is given the tools of that page directly, so it answers sooner."
          }
        },
        "type": "object",
        "required": [
          "messages"
        ],
        "title": "AssistantRequest",
        "examples": [
          {
            "entity": "CH01",
            "language": "en",
            "messages": [
              {
                "role": "user",
                "text": "Show me unearned revenue this year to date."
              }
            ],
            "page": "/analytics"
          }
        ]
      },
      "AttachmentOut": {
        "properties": {
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "File name of the attachment, e.g. `INV-2026-000001.pdf`."
          },
          "content_type": {
            "type": "string",
            "title": "Content Type",
            "description": "Media type, e.g. `application/pdf`."
          },
          "size": {
            "type": "integer",
            "title": "Size",
            "description": "Size in bytes."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the attached bytes, hex."
          }
        },
        "type": "object",
        "required": [
          "filename",
          "content_type",
          "size",
          "sha256"
        ],
        "title": "AttachmentOut"
      },
      "AttemptOut": {
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time",
            "title": "At",
            "description": "When the attempt was made."
          },
          "status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "The HTTP status the endpoint answered."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why it failed, when it did not answer 2xx."
          },
          "ms": {
            "type": "integer",
            "title": "Ms",
            "description": "How long it took, in milliseconds."
          }
        },
        "type": "object",
        "required": [
          "at",
          "status",
          "error",
          "ms"
        ],
        "title": "AttemptOut"
      },
      "AuditEventOut": {
        "properties": {
          "id": {
            "type": "integer",
            "title": "Id",
            "description": "Sequence number of the event; rises with time."
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "title": "At",
            "description": "When it happened (ISO 8601, UTC)."
          },
          "actor": {
            "additionalProperties": true,
            "type": "object",
            "title": "Actor",
            "description": "The actor, as stored in the audit trail: an object with `type` (`human`, `agent` or `system`), `id` (`user:<id>`, `key:<prefix>` or `system:<name>`) and `name`."
          },
          "action": {
            "type": "string",
            "title": "Action",
            "description": "What happened, e.g. `journal.post`, `approval.approved`, `period.close`, `api_key.create`."
          },
          "object_type": {
            "type": "string",
            "title": "Object Type",
            "description": "Kind of object affected, e.g. `journal_entry`, `period`, `entity`."
          },
          "object_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Object Id",
            "description": "Id of the object, as text; null when there is none."
          },
          "request_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Request Id",
            "description": "The `X-Request-Id` of the request that caused it; null if none."
          },
          "idempotency_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Idempotency Key",
            "description": "The `Idempotency-Key` of that request; null if none."
          },
          "data": {
            "additionalProperties": true,
            "type": "object",
            "title": "Data",
            "description": "Event-specific details, e.g. the entry number and hash of a posting."
          }
        },
        "type": "object",
        "required": [
          "id",
          "at",
          "actor",
          "action",
          "object_type",
          "object_id",
          "request_id",
          "idempotency_key",
          "data"
        ],
        "title": "AuditEventOut"
      },
      "AuditFileOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "Entity country (ISO 3166-1 alpha-2)."
          },
          "formats": {
            "items": {
              "type": "string",
              "enum": [
                "evidence",
                "fec",
                "gobd",
                "saft"
              ]
            },
            "type": "array",
            "title": "Formats",
            "description": "The formats that fit the entity's country, its tax audit file first: `fec` for France, `gobd` for Germany, `saft` (OECD SAF-T 2.0) elsewhere; then `evidence` (the audit evidence pack), for every country."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year."
          },
          "from_period": {
            "type": "integer",
            "title": "From Period",
            "description": "The first period covered."
          },
          "to_period": {
            "type": "integer",
            "title": "To Period",
            "description": "The last period covered."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day covered."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day covered."
          },
          "closing_date": {
            "type": "string",
            "format": "date",
            "title": "Closing Date",
            "description": "The last day of the fiscal year: the date in the FEC's file name."
          },
          "year_closed": {
            "type": "boolean",
            "title": "Year Closed",
            "description": "True when the fiscal year's close is approved. The files can be made before; they then cover what is posted so far, which can still change."
          },
          "open_periods": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Open Periods",
            "description": "The numbers of the covered periods that are still open (posting into them is still possible)."
          },
          "entries": {
            "type": "integer",
            "title": "Entries",
            "description": "Posted journal entries in the range."
          },
          "file_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File Name",
            "description": "The name the tax audit file (the first of `formats`) will have; null when it cannot be made (`missing`). `file_names` has the name of each format."
          },
          "file_names": {
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "enum": [
                "evidence",
                "fec",
                "gobd",
                "saft"
              ]
            },
            "type": "object",
            "title": "File Names",
            "description": "The name each format's file will have, by format; a format whose file cannot be made (`missing`) is left out.",
            "examples": [
              {
                "evidence": "Audit_Evidence_CH01_2026.zip",
                "saft": "SAF-T_CH01_2026.xml"
              }
            ]
          },
          "missing": {
            "items": {
              "type": "string",
              "const": "siren"
            },
            "type": "array",
            "title": "Missing",
            "description": "What stops the file: `siren` (an FEC is named after the company's SIREN, taken from its French VAT number, and the entity has none); empty when it can be made."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "country",
          "formats",
          "fiscal_year",
          "from_period",
          "to_period",
          "start",
          "end",
          "closing_date",
          "year_closed",
          "open_periods",
          "entries",
          "file_name",
          "file_names",
          "missing"
        ],
        "title": "AuditFileOut",
        "description": "What an audit file of an entity's fiscal year (or of a range of its periods) would cover."
      },
      "AuthConfig": {
        "properties": {
          "google_client_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Google Client Id",
            "description": "The Google OAuth client id the web UI signs in with; null when Google sign-in is not configured."
          },
          "password_sign_in": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PasswordSignIn"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where people without a Google account sign in with their e-mail address and a password (Google Identity Platform); null when it is not configured."
          },
          "dev_login": {
            "type": "boolean",
            "title": "Dev Login",
            "description": "True when the development login is enabled (never in the cloud)."
          }
        },
        "type": "object",
        "required": [
          "google_client_id",
          "dev_login"
        ],
        "title": "AuthConfig"
      },
      "AutopilotOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "today": {
            "type": "string",
            "format": "date",
            "title": "Today",
            "description": "The company's today."
          },
          "ai_budget": {
            "type": "integer",
            "title": "Ai Budget",
            "description": "Items the AI may work on for this company a day."
          },
          "ai_used": {
            "type": "integer",
            "title": "Ai Used",
            "description": "Items sent to the AI today."
          },
          "outcomes": {
            "items": {
              "$ref": "#/components/schemas/OutcomeOut"
            },
            "type": "array",
            "title": "Outcomes",
            "description": "Every outcome Autopilot can keep."
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/QuestionOut"
            },
            "type": "array",
            "title": "Questions",
            "description": "Open questions, oldest first."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "today",
          "ai_budget",
          "ai_used",
          "outcomes",
          "questions"
        ],
        "title": "AutopilotOut"
      },
      "AvailabilityDay": {
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The day (for a night: the night that starts that day)."
          },
          "units": {
            "type": "string",
            "title": "Units",
            "description": "Units the item has in the slot."
          },
          "booked": {
            "type": "string",
            "title": "Booked",
            "description": "Units booked."
          },
          "free": {
            "type": "string",
            "title": "Free",
            "description": "Units still free (never below zero)."
          }
        },
        "type": "object",
        "required": [
          "day",
          "units",
          "booked",
          "free"
        ],
        "title": "AvailabilityDay"
      },
      "AvailabilityOut": {
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Id of the capacity item's product."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Product code."
          },
          "slot": {
            "type": "string",
            "enum": [
              "day",
              "hour",
              "night"
            ],
            "title": "Slot",
            "description": "What one slot is."
          },
          "days": {
            "items": {
              "$ref": "#/components/schemas/AvailabilityDay"
            },
            "type": "array",
            "title": "Days",
            "description": "Each day asked for, in order."
          }
        },
        "type": "object",
        "required": [
          "product_id",
          "code",
          "slot",
          "days"
        ],
        "title": "AvailabilityOut"
      },
      "AverageRate": {
        "properties": {
          "month": {
            "type": "string",
            "title": "Month",
            "description": "The calendar month, `YYYY-MM`."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "Units of the report currency per one unit of the company's currency: the mean of the ECB's daily rates of the month, 10 decimals."
          },
          "fixings": {
            "type": "integer",
            "title": "Fixings",
            "description": "How many daily ECB rates the mean is of."
          },
          "first_fixing": {
            "type": "string",
            "format": "date",
            "title": "First Fixing",
            "description": "The first of those days."
          },
          "last_fixing": {
            "type": "string",
            "format": "date",
            "title": "Last Fixing",
            "description": "The last of those days."
          },
          "complete": {
            "type": "boolean",
            "title": "Complete",
            "description": "False for a month that has not ended: the mean of its rates so far, which changes as the month goes on."
          }
        },
        "type": "object",
        "required": [
          "month",
          "rate",
          "fixings",
          "first_fixing",
          "last_fixing",
          "complete"
        ],
        "title": "AverageRate"
      },
      "Balance": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the amounts."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "Open amount of posted documents (credit notes negative), less what is on account (`on_account`): what the party owes, or is owed, in this currency."
          },
          "overdue": {
            "type": "string",
            "title": "Overdue",
            "description": "The part of it due before the `as_of` day."
          },
          "on_account": {
            "type": "string",
            "title": "On Account",
            "description": "What is left on account of the party's posted payments, not yet applied to an invoice or bill (ADR-0045): received from a customer, or paid to a vendor, ahead. Positive; `open` is already less it.",
            "default": "0.00"
          },
          "open_documents": {
            "type": "integer",
            "title": "Open Documents",
            "description": "Number of documents with an open amount."
          },
          "overdue_documents": {
            "type": "integer",
            "title": "Overdue Documents",
            "description": "Number of those that are overdue."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "open",
          "overdue",
          "open_documents",
          "overdue_documents"
        ],
        "title": "Balance",
        "description": "Open posted documents of a party in one currency (credit notes count negative)."
      },
      "BalanceRow": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "dividend",
              "interest",
              "loan"
            ],
            "title": "Kind",
            "description": "`loan` (the principal), `interest` (accrued and not paid) or `dividend` (declared and not paid)."
          },
          "item_id": {
            "type": "string",
            "format": "uuid",
            "title": "Item Id",
            "description": "The loan (`GET /v1/ic/loans`), or the dividend's `dividend_declared` movement."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "The loan's or the dividend's reference."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the item."
          },
          "a_balance": {
            "type": "string",
            "title": "A Balance",
            "description": "What `entity_a` holds of it: a receivable positive, a payable negative."
          },
          "b_balance": {
            "type": "string",
            "title": "B Balance",
            "description": "What `entity_b` holds of it, signed the same way."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`a_balance + b_balance`; zero when both agree."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "amount_differs",
                  "cutoff",
                  "loan_movement_missing",
                  "mirror_draft",
                  "mirror_missing",
                  "mirror_pending_approval",
                  "mirror_rejected",
                  "payment_in_transit",
                  "unlinked_document"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "`loan_movement_missing` (an entry of a movement is not posted yet on one side: explained) or `amount_differs` (unexplained); null when they agree."
          },
          "explained": {
            "type": "boolean",
            "title": "Explained",
            "description": "True when the difference is a timing item (or zero)."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "item_id",
          "reference",
          "currency",
          "a_balance",
          "b_balance",
          "difference",
          "reason",
          "explained"
        ],
        "title": "BalanceRow",
        "description": "A loan, its accrued interest or a declared group dividend, and what the two sides hold of it\n(ADR-0025, section 6)."
      },
      "BalanceSheet": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency all amounts are in: the entity's functional currency, or the one asked for with `currency`."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The report date (ISO 8601)."
          },
          "assets": {
            "type": "string",
            "title": "Assets",
            "description": "Total assets."
          },
          "liabilities": {
            "type": "string",
            "title": "Liabilities",
            "description": "Total liabilities."
          },
          "equity": {
            "type": "string",
            "title": "Equity",
            "description": "Total equity, including `unclosed_earnings`."
          },
          "unclosed_earnings": {
            "type": "string",
            "title": "Unclosed Earnings",
            "description": "Profit or loss accumulated through `as_of` that has not been closed to retained earnings; positive is a profit. In another currency: the results of every year at their months' average rates (the closing entries are left out)."
          },
          "balanced": {
            "type": "boolean",
            "title": "Balanced",
            "description": "True when assets equal liabilities plus equity."
          },
          "sections": {
            "items": {
              "$ref": "#/components/schemas/Section"
            },
            "type": "array",
            "title": "Sections",
            "description": "Assets, liabilities and equity grouped by report line."
          },
          "translation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportTranslation"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shown in another currency than the entity's own: how it was translated and the rates used; null in the entity's own currency."
          },
          "comparative": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BalanceSheetComparative"
              },
              {
                "type": "null"
              }
            ],
            "description": "With `compare=prior_year_end` or `compare_as_of`: the totals at the comparative date and the changes; each account and section carries its own `comparative`. There is no budget comparison: budgets plan revenue and expenses only."
          },
          "notes": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Notes",
            "description": "Caveats of the comparative (`reportNote` codes), e.g. that no fiscal year contains the report date."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "as_of",
          "assets",
          "liabilities",
          "equity",
          "unclosed_earnings",
          "balanced",
          "sections"
        ],
        "title": "BalanceSheet"
      },
      "BalanceSheetComparative": {
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The comparative date: the last day of the previous fiscal year, or `compare_as_of` (ISO 8601)."
          },
          "assets": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Total assets against the comparative date."
          },
          "liabilities": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Total liabilities against it."
          },
          "equity": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Total equity against it."
          },
          "unclosed_earnings": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Unclosed earnings against it."
          }
        },
        "type": "object",
        "required": [
          "as_of",
          "assets",
          "liabilities",
          "equity",
          "unclosed_earnings"
        ],
        "title": "BalanceSheetComparative"
      },
      "BankAccountInput": {
        "properties": {
          "iban": {
            "type": "string",
            "title": "Iban",
            "description": "IBAN of the account (debit account in pain.001)."
          },
          "qr_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Qr Iban",
            "description": "QR-IBAN for QR-bills with QR reference."
          },
          "bic": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "BIC/SWIFT code of the bank (8 or 11 characters)."
          },
          "qr_reference_prefix": {
            "type": "string",
            "pattern": "^[0-9]{0,12}$",
            "title": "Qr Reference Prefix",
            "description": "Leading digits of QR references, if the bank assigns a customer id.",
            "default": ""
          },
          "holder_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Holder Name",
            "description": "Defaults to the entity name."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the account holder's address."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the account holder's address."
          },
          "postal_code": {
            "type": "string",
            "title": "Postal Code",
            "description": "Postal code of the account holder's address; required."
          },
          "town": {
            "type": "string",
            "title": "Town",
            "description": "Town of the account holder's address; required."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country of the account holder; default: the entity's country."
          },
          "creditor_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditor Id",
            "description": "SEPA creditor identifier (Gläubiger-ID) for direct debits into this account, e.g. `DE98ZZZ09999999999`: checked by its ISO 7064 check digits (422 `creditor_id_invalid`). It applies at once; only a new IBAN waits for a second person."
          }
        },
        "type": "object",
        "required": [
          "iban",
          "postal_code",
          "town"
        ],
        "title": "BankAccountInput",
        "examples": [
          {
            "building_number": "1",
            "iban": "CH93 0076 2011 6238 5295 7",
            "postal_code": "8001",
            "qr_iban": "CH64 3196 1000 0044 2155 7",
            "street": "Bahnhofstrasse",
            "town": "Zürich"
          }
        ]
      },
      "BankAccountOut": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Code of the GL bank account, e.g. `1020`."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "Name of the GL account."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the account."
          },
          "iban": {
            "type": "string",
            "title": "Iban",
            "description": "IBAN of the account (debit account of payment files)."
          },
          "qr_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Qr Iban",
            "description": "QR-IBAN for QR-bills with QR reference, if any."
          },
          "bic": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "BIC/SWIFT code of the bank."
          },
          "qr_reference_prefix": {
            "type": "string",
            "title": "Qr Reference Prefix",
            "description": "Leading digits of QR references (a bank customer id)."
          },
          "holder_name": {
            "type": "string",
            "title": "Holder Name",
            "description": "Name of the account holder."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the holder's address."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the holder's address."
          },
          "postal_code": {
            "type": "string",
            "title": "Postal Code",
            "description": "Postal code of the holder's address."
          },
          "town": {
            "type": "string",
            "title": "Town",
            "description": "Town of the holder's address."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country of the holder."
          },
          "creditor_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditor Id",
            "description": "SEPA creditor identifier the company collects direct debits with into this account (e.g. `DE98ZZZ09999999999`); null when it collects none."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When the details were last registered (UTC)."
          },
          "status": {
            "type": "string",
            "enum": [
              "applied",
              "pending_approval"
            ],
            "title": "Status",
            "description": "`pending_approval` while a change of these details waits for a second person (then `approval_id` names the request); a registration answered with it shows the details that apply once it is approved.",
            "default": "applied"
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request of a change that waits, if any."
          }
        },
        "type": "object",
        "required": [
          "account",
          "account_name",
          "currency",
          "iban",
          "qr_iban",
          "bic",
          "qr_reference_prefix",
          "holder_name",
          "street",
          "building_number",
          "postal_code",
          "town",
          "country"
        ],
        "title": "BankAccountOut"
      },
      "BankBalance": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the bills."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Code of the bank account they are paid from."
          },
          "account_currency": {
            "type": "string",
            "title": "Account Currency",
            "description": "The currency the account holds."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "Its book balance on the payment date (posted entries), less the outgoing payments from it the bank has not executed yet (ADR-0060), in `account_currency`."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "account",
          "account_currency",
          "balance"
        ],
        "title": "BankBalance"
      },
      "BankConfirmation": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the bank statement line."
          },
          "statement_id": {
            "type": "string",
            "format": "uuid",
            "title": "Statement Id",
            "description": "Id of its bank statement."
          },
          "booking_date": {
            "type": "string",
            "format": "date",
            "title": "Booking Date",
            "description": "The day the bank booked it."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The amount on the bank line, signed as the bank shows it."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the bank line."
          }
        },
        "type": "object",
        "required": [
          "id",
          "statement_id",
          "booking_date",
          "amount",
          "currency"
        ],
        "title": "BankConfirmation"
      },
      "BankItem": {
        "properties": {
          "line_id": {
            "type": "string",
            "format": "uuid",
            "title": "Line Id",
            "description": "The statement line (`GET .../bank-lines`)."
          },
          "booking_date": {
            "type": "string",
            "format": "date",
            "title": "Booking Date",
            "description": "Day the bank booked it, ISO 8601."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What is missing from the ledger, signed (positive is money in): the line's amount, or the part of it not booked by the date."
          },
          "counterparty": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty",
            "description": "Who paid or was paid, as the bank names them."
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Text",
            "description": "The line's reference or remittance text."
          },
          "statement_ref": {
            "type": "string",
            "title": "Statement Ref",
            "description": "The statement the line came with."
          },
          "reason": {
            "type": "string",
            "enum": [
              "booked_later",
              "ignored",
              "unmatched",
              "waiting_for_approval"
            ],
            "title": "Reason",
            "description": "`unmatched`: nobody matched it yet; `ignored`: a person ignored it, so it is never booked; `waiting_for_approval`: its booking waits for a second person; `booked_later`: it is booked after the date."
          }
        },
        "type": "object",
        "required": [
          "line_id",
          "booking_date",
          "amount",
          "counterparty",
          "text",
          "statement_ref",
          "reason"
        ],
        "title": "BankItem",
        "description": "A statement line up to the date that the ledger does not show by then."
      },
      "BankLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Bank line id."
          },
          "statement_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Statement Id",
            "description": "Statement the line was imported with."
          },
          "booking_date": {
            "type": "string",
            "format": "date",
            "title": "Booking Date",
            "description": "Booking date at the bank, ISO 8601: the statement's date, and the date postings use unless its period is closed (`posting_date`)."
          },
          "value_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value Date",
            "description": "Value date, ISO 8601, when the file gives one."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Signed amount in `currency`: positive is money in, negative money out."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency code of the line."
          },
          "counterparty_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Name",
            "description": "Name of the other party as on the statement."
          },
          "counterparty_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Iban",
            "description": "IBAN of the other party, when given."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Payment reference (QR or ISO 11649 creditor reference), when given."
          },
          "end_to_end_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "End To End Id",
            "description": "End-to-end id; equals the number of a payment sent in a pain.001 file."
          },
          "remittance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remittance",
            "description": "Free remittance text."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`unmatched`, `matched` or `ignored`."
          },
          "match": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Match",
            "description": "How the line was settled, null while unmatched: `kind` (`payment`, `journal`, `ignored`, or `return` for a credit that returned an outgoing payment, with its `payment` number, ADR-0062), `method` (`rule`, `manual` or `agent`), `reasons`, `by` (the actor), `status` of the payment or entry, `booked_on` when it was booked on another day than the booking date (its period was closed), or `reason` for ignored lines; `undo` (`status` `pending_approval`, `approval_id`) while undoing the match waits for a second person, and on an unmatched line `undone` or `rejected` when a match was taken back."
          },
          "posting_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Date",
            "description": "For an unmatched line: the day a match or posting books it on by default, its booking date, or when that is in a closed period the first day of the next open period (send another as `on`); null for a line that is not unmatched."
          },
          "closed_period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed Period",
            "description": "For an unmatched line whose booking date is in a closed period: that period, e.g. `2026-08`, the reason `posting_date` is later; else null."
          },
          "payment_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Id",
            "description": "Payment created by a match, when the line was matched to documents."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "Journal entry created by posting the line to an account."
          }
        },
        "type": "object",
        "required": [
          "id",
          "booking_date",
          "amount",
          "currency",
          "counterparty_name",
          "counterparty_iban",
          "reference",
          "remittance",
          "status",
          "match"
        ],
        "title": "BankLineOut"
      },
      "BankReconciliationView": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "The bank account reconciled."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "The account's name in the user's language."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency the account holds; every amount is in it."
          },
          "on": {
            "type": "string",
            "format": "date",
            "title": "On",
            "description": "The statement date the balances are taken on."
          },
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/ReconcileAccount"
            },
            "type": "array",
            "title": "Accounts",
            "description": "The entity's bank accounts."
          },
          "statements": {
            "items": {
              "$ref": "#/components/schemas/StatementDate"
            },
            "type": "array",
            "title": "Statements",
            "description": "The account's statements with an end date, newest first (camt.054 notifications carry no balance and are left out)."
          },
          "since": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Since",
            "description": "The first day of the account's statements: entries before it are not compared. Null when no statement was imported for the account."
          },
          "statement_ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Statement Ref",
            "description": "The statement ending on the date, if any."
          },
          "statement_balance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Statement Balance",
            "description": "The statement's closing balance, or the balance given in the request when no statement for the date carries one; null when neither is known."
          },
          "ledger_balance": {
            "type": "string",
            "title": "Ledger Balance",
            "description": "The posted balance of the account on the date."
          },
          "difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Difference",
            "description": "Statement balance less ledger balance."
          },
          "opening_difference": {
            "type": "string",
            "title": "Opening Difference",
            "description": "The first statement's opening balance less the ledger balance the day before it: what differed already before any statement line."
          },
          "bank_items": {
            "items": {
              "$ref": "#/components/schemas/BankItem"
            },
            "type": "array",
            "title": "Bank Items",
            "description": "In the bank, not yet in the ledger."
          },
          "bank_items_total": {
            "type": "string",
            "title": "Bank Items Total",
            "description": "The sum of the bank items."
          },
          "ledger_items": {
            "items": {
              "$ref": "#/components/schemas/LedgerItem"
            },
            "type": "array",
            "title": "Ledger Items",
            "description": "In the ledger, not yet in the bank."
          },
          "ledger_items_total": {
            "type": "string",
            "title": "Ledger Items Total",
            "description": "The sum of the ledger items."
          },
          "unexplained": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unexplained",
            "description": "What the items do not explain: difference less opening difference, less bank items, plus ledger items. Zero when the account is reconciled."
          },
          "done": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReconciliationDone"
              },
              {
                "type": "null"
              }
            ],
            "description": "The record of the person who marked this account and date reconciled."
          }
        },
        "type": "object",
        "required": [
          "account",
          "account_name",
          "currency",
          "on",
          "accounts",
          "statements",
          "since",
          "statement_ref",
          "statement_balance",
          "ledger_balance",
          "difference",
          "opening_difference",
          "bank_items",
          "bank_items_total",
          "ledger_items",
          "ledger_items_total",
          "unexplained",
          "done"
        ],
        "title": "BankReconciliationView"
      },
      "BankRefusal": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "rejected",
              "returned"
            ],
            "title": "Kind",
            "description": "`rejected`: the bank refused the payment in its status report (pain.002) and never paid it; `returned`: the bank paid it and the money came back (a credit line on a statement)."
          },
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "The bank's reason as an ISO 20022 code, e.g. `AC04` (account closed), `AC01` (account number wrong); null when the bank gives none."
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Text",
            "description": "The bank's own words, as it sent them, if any."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Where the bank said so: the status report's message id, or the bank reference of the statement line that returned the money."
          },
          "on": {
            "type": "string",
            "format": "date",
            "title": "On",
            "description": "The day the payment's reversal is dated."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "`posted`: the payment is reversed and the documents it paid are open again; `pending_approval`: its reversal waits for a second person (four eyes)."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "code",
          "text",
          "source",
          "on",
          "status"
        ],
        "title": "BankRefusal"
      },
      "BillReading": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "read",
              "waiting"
            ],
            "title": "Status",
            "description": "`read`: the file was read (`extracted`); `waiting`: no language model answered in time, so nothing was read or stored: send the same file again after `retry_after_seconds` (the bill wizard does it by itself).",
            "default": "read"
          },
          "retry_after_seconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Retry After Seconds",
            "description": "For `waiting`: when to send the file again; else null."
          },
          "source": {
            "type": "string",
            "enum": [
              "einvoice",
              "model"
            ],
            "title": "Source",
            "description": "`einvoice`: read from structured XML, no model call; `model`: read by the language model."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "Id of the stored file with the model's reading; null for an e-invoice (stored when its bill is created)."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the file."
          },
          "extracted": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExtractedBill"
              },
              {
                "type": "null"
              }
            ],
            "description": "What was read from the file; null while `waiting`."
          },
          "vendor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VendorMatch"
              },
              {
                "type": "null"
              }
            ],
            "description": "The known vendor the bill matches (by VAT number, IBAN or name); null for an unknown one."
          },
          "new_vendor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VendorProposal"
              },
              {
                "type": "null"
              }
            ],
            "description": "For an unknown vendor: its master data as the bill gives it."
          },
          "bookable": {
            "type": "boolean",
            "title": "Bookable",
            "description": "`true` when a bill can be created from it: an invoice with a date and lines (and, for an e-invoice, no fatal rule broken)."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "What to look at before creating the bill."
          },
          "einvoice": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CheckResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "For an e-invoice: its rule check; else null."
          }
        },
        "type": "object",
        "required": [
          "source",
          "document_id",
          "sha256",
          "extracted",
          "vendor",
          "new_vendor",
          "bookable",
          "warnings"
        ],
        "title": "BillReading",
        "description": "What a vendor bill says, before anything is booked."
      },
      "BlockerOut": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Names the reason, like an error code."
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "The reason in plain English."
          },
          "details": {
            "additionalProperties": true,
            "type": "object",
            "title": "Details",
            "description": "The values the message names."
          }
        },
        "type": "object",
        "required": [
          "code",
          "message",
          "details"
        ],
        "title": "BlockerOut",
        "description": "What stops an action, as a refusal would say it: a screen words ``code`` from ``details``\nin the person's language and shows ``message`` (English) for a code it does not know."
      },
      "Body_attach_file_v1_documents__document_id__files_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The original: a PDF, PNG, JPEG or WebP file, at most 20 MB. Its type is read from its bytes, whatever its name or declared type."
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_attach_file_v1_documents__document_id__files_post"
      },
      "Body_capture_bill_v1_agents_bill_capture_post": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity the bill is for, e.g. `CH01`.",
            "examples": [
              "CH01"
            ]
          },
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The vendor invoice: PDF, PNG, JPEG or WebP, or an e-invoice (XRechnung XML, or a ZUGFeRD / Factur-X PDF); at most 20 MB."
          },
          "vendor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor",
            "description": "Code of the vendor, e.g. `V-CLOUD`, if you know it; otherwise the vendor is matched by VAT number, IBAN or name.",
            "examples": [
              "V-CLOUD"
            ]
          },
          "create_vendor": {
            "type": "boolean",
            "title": "Create Vendor",
            "description": "`true` (default): create the vendor when none matches (the approval policy may require a second person to activate it); `false`: answer `needs_review` instead.",
            "default": true
          },
          "line_accounts": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line Accounts",
            "description": "Optional JSON array of reviewed account codes, one per captured line. Every account must be an allowed expense or asset account of this company. The stored extraction is kept unchanged; the reviewed choices are used for this bill.",
            "examples": [
              "[\"6500\"]"
            ]
          }
        },
        "type": "object",
        "required": [
          "entity",
          "file"
        ],
        "title": "Body_capture_bill_v1_agents_bill_capture_post"
      },
      "Body_check_einvoice_v1_einvoices_check_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The e-invoice: an XRechnung XML file (UBL or CII) or a ZUGFeRD / Factur-X PDF with the XML embedded. At most 20 MB."
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_check_einvoice_v1_einvoices_check_post"
      },
      "Body_claim_receipt_v1_expenses_receipts_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The receipt: a photo (JPEG, PNG, WebP) or a PDF; at most 20 MB."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code of the company it is for; default as `POST /v1/expenses`."
          },
          "submit": {
            "type": "boolean",
            "title": "Submit",
            "description": "Submit it at once, as read and filled, without a check.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_claim_receipt_v1_expenses_receipts_post"
      },
      "Body_import_einvoice_v1_documents_einvoice_post": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity that receives the bill, e.g. `DE01`."
          },
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The e-invoice: an XRechnung XML file (UBL or CII) or a ZUGFeRD / Factur-X PDF with the XML embedded. At most 20 MB."
          },
          "vendor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor",
            "description": "Vendor code, e.g. `V-IT`; default: the vendor is found by the seller's VAT id, then by IBAN."
          },
          "create_vendor": {
            "type": "boolean",
            "title": "Create Vendor",
            "description": "Create an unknown vendor as a draft vendor from the seller's details (`true`, default); `false` answers status `needs_review` instead.",
            "default": true
          },
          "submit": {
            "type": "boolean",
            "title": "Submit",
            "description": "`true`: also submit the bill through the approval policy; `false` (default): leave it a draft.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "entity",
          "file"
        ],
        "title": "Body_import_einvoice_v1_documents_einvoice_post"
      },
      "Body_import_file_v1_entities__entity__imports_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The file (multipart form field `file`): CSV (UTF-8; `,`, `;` or tab delimited) or Excel `.xlsx`, whose first row names the columns of the template (`GET /v1/entities/{entity}/imports/templates/{type}`); at most 5 MB and 2,000 rows."
          },
          "type": {
            "type": "string",
            "enum": [
              "accounts",
              "customers",
              "open_payables",
              "open_receivables",
              "opening_balances",
              "vendors"
            ],
            "title": "Type",
            "description": "What the rows are: `customers`, `vendors`, `accounts`, `opening_balances` (the trial balance of the old books), `open_receivables` or `open_payables` (the invoices and bills still open)."
          },
          "mode": {
            "type": "string",
            "enum": [
              "commit",
              "dry_run"
            ],
            "title": "Mode",
            "description": "`dry_run` (the default) checks everything and saves nothing; `commit` applies the whole file or nothing and needs an `Idempotency-Key`.",
            "default": "dry_run",
            "examples": [
              "commit"
            ]
          },
          "as_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "As Of",
            "description": "The opening date, `YYYY-MM-DD`: the day the new books start and the opening entries are dated (the balances are those at the end of the day before). Required for `opening_balances`, `open_receivables` and `open_payables`, whose period must be open; ignored by the other types.",
            "examples": [
              "2026-01-01"
            ]
          },
          "confirm_rates": {
            "type": "boolean",
            "title": "Confirm Rates",
            "description": "Use the `fx_rate` values of the file even where one differs by more than 10% from the reference rate (ECB) of the opening date. Without it such a row is a problem (`rates_to_confirm` counts them); with it the row is imported and listed as a warning.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "file",
          "type"
        ],
        "title": "Body_import_file_v1_entities__entity__imports_post"
      },
      "Body_import_salesforce_v1_entities__entity__imports_salesforce_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The export (multipart form field `file`): a CSV as Salesforce writes it (the weekly Data Export, Data Loader, Workbench or a report) or an Excel `.xlsx`; at most 20 MB, 10,000 rows and 800 columns."
          },
          "object": {
            "type": "string",
            "enum": [
              "accounts",
              "contacts",
              "events",
              "notes",
              "opportunities",
              "price_book_entries",
              "price_books",
              "products",
              "tasks",
              "users"
            ],
            "title": "Object",
            "description": "What the file holds, imported in this order: `users` (User), `accounts` (Account), `products` (Product2), `price_books` (Pricebook2), `price_book_entries` (PricebookEntry), `opportunities` (Opportunity), `tasks` (Task), `events` (Event), `notes` (Note)."
          },
          "mode": {
            "type": "string",
            "enum": [
              "commit",
              "dry_run"
            ],
            "title": "Mode",
            "description": "`dry_run` (the default) checks everything and saves nothing; `commit` applies the whole file or nothing and needs an `Idempotency-Key`.",
            "default": "dry_run",
            "examples": [
              "commit"
            ]
          },
          "mapping": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mapping",
            "description": "Optional JSON object: our field -> the file's column to read it from, or null to leave it empty. Fields it does not name are found by their Salesforce names (the `mapping` of a dry run shows what was found).",
            "examples": [
              "{\"vat_number\": \"UID__c\", \"description\": null}"
            ]
          }
        },
        "type": "object",
        "required": [
          "file",
          "object"
        ],
        "title": "Body_import_salesforce_v1_entities__entity__imports_salesforce_post"
      },
      "Body_import_statement_v1_entities__entity__bank_statements_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The statement file (multipart form field `file`), at most 10 MB."
          },
          "format": {
            "type": "string",
            "enum": [
              "camt053",
              "camt054",
              "csv",
              "mt940"
            ],
            "title": "Format",
            "description": "File format: `camt053` (statement, the default), `camt054` (debit/credit notification), `mt940` (SWIFT MT940 statement) or `csv` (columns described by `csv_mapping`).",
            "default": "camt053"
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "GL bank account code the statement belongs to, e.g. `1020`. Default: the account registered for the statement's IBAN, else the entity's bank account."
          },
          "csv_mapping": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Csv Mapping",
            "description": "CSV only: a JSON object (as a string) naming the file's columns, with keys `date`, `amount`, `credit` and `debit` (separate columns of money in and out, in place of `amount`), `currency`, `counterparty`, `iban`, `reference`, `description`, `bank_reference`, `date_format` (strptime, default `%Y-%m-%d`), `decimal_comma`, `delimiter` and `default_currency`. Default: columns named `date`, `amount`, `counterparty`, `reference`, `description`. A named column the file lacks is refused (`csv_column_missing`); `POST .../bank-statements/preview` guesses the mapping and shows what it reads."
          },
          "auto_match": {
            "type": "boolean",
            "title": "Auto Match",
            "description": "Run the automatic matcher on the imported lines (default true); false leaves every line unmatched.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_import_statement_v1_entities__entity__bank_statements_post"
      },
      "Body_import_status_report_v1_entities__entity__payment_status_reports_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The pain.002 file (multipart form field `file`), at most 10 MB."
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_import_status_report_v1_entities__entity__payment_status_reports_post"
      },
      "Body_preview_statement_v1_entities__entity__bank_statements_preview_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The CSV file (multipart form field `file`), at most 10 MB."
          },
          "format": {
            "type": "string",
            "const": "csv",
            "title": "Format",
            "description": "File format: `csv`.",
            "default": "csv"
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "GL bank account code the lines would be booked on, e.g. `1020`. Default: the entity's bank account."
          },
          "csv_mapping": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Csv Mapping",
            "description": "A JSON object (as a string) naming the file's columns, as for the import. Default: guessed from the file."
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_preview_statement_v1_entities__entity__bank_statements_preview_post"
      },
      "Body_read_bill_v1_agents_bill_capture_read_post": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity the bill is for, e.g. `CH01`.",
            "examples": [
              "CH01"
            ]
          },
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The vendor invoice: PDF, PNG, JPEG or WebP, or an e-invoice (XRechnung XML, or a ZUGFeRD / Factur-X PDF); at most 20 MB."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "file"
        ],
        "title": "Body_read_bill_v1_agents_bill_capture_read_post"
      },
      "Body_read_expense_card_statement_v1_expense_cards__card_id__statement_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "The issuer's statement: CSV or .xlsx with a date, amount and merchant."
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_read_expense_card_statement_v1_expense_cards__card_id__statement_post"
      },
      "Body_upload_logo_v1_entities__entity__brand_logo_post": {
        "properties": {
          "file": {
            "type": "string",
            "contentMediaType": "application/octet-stream",
            "title": "File",
            "description": "A PNG, JPEG, WebP or GIF image, at most 2 MB. SVG is refused."
          }
        },
        "type": "object",
        "required": [
          "file"
        ],
        "title": "Body_upload_logo_v1_entities__entity__brand_logo_post"
      },
      "BookInput": {
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z0-9_-]{2,20}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "e.g. `TAX-CH`; left out, it is made from the name (`TAX-BOOK-SWITZERLAND`)."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "title": "Name",
            "description": "Book name, e.g. `Tax book Switzerland (ESTV)`."
          },
          "regime": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Regime",
            "description": "data-vNext depreciation regime, e.g. ch.estv, de.afa, us.macrs.gds"
          },
          "deferred_tax": {
            "type": "boolean",
            "title": "Deferred Tax",
            "description": "Post deferred tax from this book.",
            "default": false
          },
          "tax_rate_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate Percent",
            "description": "Tax rate in percent (above 0, below 100), e.g. `12.0`. Required when `deferred_tax` is true."
          },
          "deferred_tax_cadence": {
            "type": "string",
            "enum": [
              "period",
              "year_end"
            ],
            "title": "Deferred Tax Cadence",
            "description": "Whether the close needs a deferred-tax run every period or only at year end.",
            "default": "year_end"
          },
          "dtl_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dtl Account",
            "description": "Deferred tax liability account (default: role)."
          },
          "dta_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dta Account",
            "description": "Deferred tax asset account (default: role)."
          },
          "dt_expense_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dt Expense Account",
            "description": "Deferred tax expense/income account (default: role)."
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "BookInput",
        "examples": [
          {
            "code": "TAX-CH",
            "deferred_tax": true,
            "name": "Tax book Switzerland (ESTV)",
            "regime": "ch.estv",
            "tax_rate_percent": "12.0"
          }
        ]
      },
      "BookOut": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Book code: `BOOK` for the accounting book, else a tax book such as `TAX-CH`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Book name."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`book` for the accounting book, `tax` for a tax book."
          },
          "standard": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Standard",
            "description": "The framework (accounting book) or data-vNext regime (tax book)."
          },
          "posts_to_gl": {
            "type": "boolean",
            "title": "Posts To Gl",
            "description": "true only for the accounting book, which posts depreciation."
          },
          "deferred_tax": {
            "type": "boolean",
            "title": "Deferred Tax",
            "description": "true when this book carries deferred tax."
          },
          "tax_rate_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate Percent",
            "description": "Tax rate in percent used for deferred tax."
          },
          "deferred_tax_cadence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deferred Tax Cadence",
            "description": "`period` or `year_end`, for the book that carries deferred tax."
          },
          "dtl_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dtl Account",
            "description": "GL account code of the deferred tax liability."
          },
          "dta_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dta Account",
            "description": "GL account code of the deferred tax asset."
          },
          "dt_expense_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dt Expense Account",
            "description": "GL account code of the deferred tax expense or income."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "kind",
          "standard",
          "posts_to_gl",
          "deferred_tax",
          "tax_rate_percent",
          "deferred_tax_cadence",
          "dtl_account",
          "dta_account",
          "dt_expense_account"
        ],
        "title": "BookOut"
      },
      "BookTotal": {
        "properties": {
          "book": {
            "type": "string",
            "title": "Book",
            "description": "Tax book code."
          },
          "tax_rate_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate Percent",
            "description": "Tax rate in percent, for the book that carries deferred tax."
          },
          "temporary_difference": {
            "type": "string",
            "title": "Temporary Difference",
            "description": "Sum of the book's temporary differences."
          },
          "deferred_tax": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deferred Tax",
            "description": "Net deferred tax: positive a liability, negative an asset."
          },
          "deferred_tax_liability": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deferred Tax Liability",
            "description": "The liability to be carried (never negative)."
          },
          "deferred_tax_asset": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deferred Tax Asset",
            "description": "The asset to be carried (never negative)."
          },
          "posted_liability": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posted Liability",
            "description": "Balance already posted on the liability account for this book."
          },
          "posted_asset": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posted Asset",
            "description": "Balance already posted on the asset account for this book."
          },
          "movement": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Movement",
            "description": "The change in deferred tax a run would post now: an increase of the net liability positive. Of it, `surplus_movement` is charged to the revaluation surplus and the rest is deferred tax expense (positive) or income (negative)."
          },
          "surplus_movement": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Surplus Movement",
            "description": "The part of `movement` charged to the revaluation surplus in equity, not to profit or loss (IAS 12.61A): the deferred tax on the surplus of the book's revalued assets, less what runs charged to it before. Zero without revaluations."
          }
        },
        "type": "object",
        "required": [
          "book",
          "tax_rate_percent",
          "temporary_difference",
          "deferred_tax",
          "deferred_tax_liability",
          "deferred_tax_asset",
          "posted_liability",
          "posted_asset",
          "movement"
        ],
        "title": "BookTotal"
      },
      "BookUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New book name. Omitted: unchanged."
          },
          "tax_rate_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate Percent",
            "description": "New tax rate in percent (above 0, below 100); the next deferred-tax run remeasures. Omitted: unchanged."
          },
          "deferred_tax_cadence": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "period",
                  "year_end"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Deferred Tax Cadence",
            "description": "`period` or `year_end`: how often the close needs a deferred-tax run. Omitted: unchanged."
          }
        },
        "type": "object",
        "title": "BookUpdate",
        "examples": [
          {
            "tax_rate_percent": "11.9"
          }
        ]
      },
      "BookingInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity that sells the item."
          },
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code (or id) of the capacity item."
          },
          "customer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer",
            "description": "Code (or id) of the customer it is for; omitted: none named."
          },
          "first_day": {
            "type": "string",
            "format": "date",
            "title": "First Day",
            "description": "The first day (or night) booked."
          },
          "last_day": {
            "type": "string",
            "format": "date",
            "title": "Last Day",
            "description": "The last day (or night) booked, included: a stay that leaves on the 5th books the nights up to the 4th. At most a year after the first."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Quantity",
            "description": "Units booked in each slot: rooms, seats or people, or hours a day."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The customer's reference or a guest's name."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A note."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "item",
          "first_day",
          "last_day",
          "quantity"
        ],
        "title": "BookingInput",
        "examples": [
          {
            "customer": "C-CH",
            "entity": "CH01",
            "first_day": "2026-11-03",
            "item": "ROOM-DBL",
            "last_day": "2026-11-04",
            "quantity": "2",
            "reference": "Offsite Zürich Kunde AG"
          }
        ]
      },
      "BookingOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Booking id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Booking number, gap-free per entity and year (BK-...)."
          },
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Id of the capacity item's product."
          },
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code of the item."
          },
          "item_name": {
            "type": "string",
            "title": "Item Name",
            "description": "Product name of the item."
          },
          "slot": {
            "type": "string",
            "enum": [
              "day",
              "hour",
              "night"
            ],
            "title": "Slot",
            "description": "What one slot is."
          },
          "customer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer",
            "description": "Customer code; null when none is named."
          },
          "customer_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Name",
            "description": "Customer name."
          },
          "first_day": {
            "type": "string",
            "format": "date",
            "title": "First Day",
            "description": "First day (or night) booked."
          },
          "last_day": {
            "type": "string",
            "format": "date",
            "title": "Last Day",
            "description": "Last day (or night) booked, included."
          },
          "slots": {
            "type": "integer",
            "title": "Slots",
            "description": "How many slots (days or nights) it covers."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Units booked in each slot."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Reference."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Note."
          },
          "status": {
            "type": "string",
            "enum": [
              "booked",
              "cancelled"
            ],
            "title": "Status",
            "description": "`booked` or `cancelled`."
          },
          "held_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Held By",
            "description": "The module that keeps the booking (`hospitality`: a hotel stay's rooms), which alone cancels it; null when it was booked here."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who booked it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "cancelled_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancelled By",
            "description": "Who cancelled it."
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancelled At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "product_id",
          "item",
          "item_name",
          "slot",
          "customer",
          "customer_name",
          "first_day",
          "last_day",
          "slots",
          "quantity",
          "reference",
          "note",
          "status",
          "held_by",
          "created_by",
          "created_at",
          "cancelled_by",
          "cancelled_at"
        ],
        "title": "BookingOut"
      },
      "BrandOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "theme": {
            "type": "string",
            "enum": [
              "dark",
              "light",
              "system"
            ],
            "title": "Theme",
            "description": "How the app looks in this company: `light`, `dark` or `system` (the device's setting)."
          },
          "colour": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Colour",
            "description": "The brand colour, `#rrggbb`; null: the product's own."
          },
          "accent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accent",
            "description": "The accent colour, `#rrggbb`; null: the brand colour."
          },
          "effective_colour": {
            "type": "string",
            "title": "Effective Colour",
            "description": "The brand colour in use (the default when none)."
          },
          "effective_accent": {
            "type": "string",
            "title": "Effective Accent",
            "description": "The accent colour in use."
          },
          "logo": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LogoOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The logo; null: none."
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/ContrastOut"
            },
            "type": "array",
            "title": "Checks",
            "description": "The contrast of the colours in use."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When it was last changed; null: never."
          },
          "updated_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "theme",
          "colour",
          "accent",
          "effective_colour",
          "effective_accent",
          "logo",
          "checks",
          "updated_at",
          "updated_by"
        ],
        "title": "BrandOut",
        "description": "A company's brand as the app, its documents and its pages show it."
      },
      "BrandUpdate": {
        "properties": {
          "theme": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "dark",
                  "light",
                  "system"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Theme",
            "description": "`light`, `dark` or `system`."
          },
          "colour": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 7
              },
              {
                "type": "null"
              }
            ],
            "title": "Colour",
            "description": "`#rrggbb` (or `#rgb`); at least 4.5:1 against white. `null`: the default."
          },
          "accent": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 7
              },
              {
                "type": "null"
              }
            ],
            "title": "Accent",
            "description": "`#rrggbb` (or `#rgb`); at least 3:1 against white. `null`: the brand colour."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "BrandUpdate",
        "description": "Only the fields sent change; `null` sets a colour back to the default.",
        "examples": [
          {
            "colour": "#1d4ed8",
            "theme": "system"
          }
        ]
      },
      "Breakdown": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "kind": {
            "type": "string",
            "enum": [
              "currency",
              "customers",
              "expense_mix",
              "vendors"
            ],
            "title": "Kind",
            "description": "What is broken down."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; amounts are in it."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range (ISO 8601)."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "The sum over all rows, including `other`."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/BreakdownRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "The largest first, at most `limit`; what is left is one row `other`."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "kind",
          "currency",
          "start",
          "end",
          "total",
          "rows"
        ],
        "title": "Breakdown"
      },
      "BreakdownRow": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "The customer or vendor code, the currency, the report line, or `other`.",
            "examples": [
              "C-DE"
            ]
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "The customer or vendor name, the currency, or the report line."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The amount in the functional currency."
          },
          "share_pct": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Share Pct",
            "description": "Its share of `total`, one decimal; null when the total is zero."
          },
          "documents": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Documents",
            "description": "How many posted documents make it up (null for the expense mix, which is read from the ledger); the filtered document list shows the same count."
          }
        },
        "type": "object",
        "required": [
          "key",
          "label",
          "amount",
          "share_pct",
          "documents"
        ],
        "title": "BreakdownRow"
      },
      "BucketPercent-Input": {
        "properties": {
          "bucket": {
            "type": "string",
            "enum": [
              "1-30",
              "31-60",
              "61-90",
              "90+",
              "current"
            ],
            "title": "Bucket",
            "description": "The aging bucket: `current` (not yet due) or days past due (`1-30`, `31-60`, `61-90`, `90+`)."
          },
          "percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Percent",
            "description": "The share of these receivables the general allowance covers."
          }
        },
        "type": "object",
        "required": [
          "bucket",
          "percent"
        ],
        "title": "BucketPercent"
      },
      "BucketPercent-Output": {
        "properties": {
          "bucket": {
            "type": "string",
            "enum": [
              "1-30",
              "31-60",
              "61-90",
              "90+",
              "current"
            ],
            "title": "Bucket",
            "description": "The aging bucket: `current` (not yet due) or days past due (`1-30`, `31-60`, `61-90`, `90+`)."
          },
          "percent": {
            "type": "string",
            "title": "Percent",
            "description": "The share of these receivables the general allowance covers."
          }
        },
        "type": "object",
        "required": [
          "bucket",
          "percent"
        ],
        "title": "BucketPercent"
      },
      "BucketTotal": {
        "properties": {
          "bucket": {
            "type": "string",
            "enum": [
              "1-30",
              "31-60",
              "61-90",
              "90+",
              "current"
            ],
            "title": "Bucket",
            "description": "The aging bucket."
          },
          "percent": {
            "type": "string",
            "title": "Percent",
            "description": "The general allowance's percent for it."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "The receivables of the bucket not marked doubtful."
          },
          "allowance": {
            "type": "string",
            "title": "Allowance",
            "description": "Their general allowance."
          }
        },
        "type": "object",
        "required": [
          "bucket",
          "percent",
          "base",
          "allowance"
        ],
        "title": "BucketTotal"
      },
      "BudgetComparative": {
        "properties": {
          "versions": {
            "items": {
              "$ref": "#/components/schemas/BudgetVersionRef"
            },
            "type": "array",
            "title": "Versions",
            "description": "The budget versions compared with: per fiscal year in the range, the approved version of a budget of that year (of several budgets, the one approved last)."
          },
          "periods": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Periods",
            "description": "The fiscal periods whose budget counts, `<year>-<number>`, e.g. `2026-09`: the regular periods wholly in the range (a budget is planned per period)."
          },
          "revenue": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Total revenue against the budget."
          },
          "expenses": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Total expenses against the budget."
          },
          "net_income": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Net income against the budget."
          }
        },
        "type": "object",
        "required": [
          "versions",
          "periods",
          "revenue",
          "expenses",
          "net_income"
        ],
        "title": "BudgetComparative"
      },
      "BudgetVersionRef": {
        "properties": {
          "plan_id": {
            "type": "string",
            "format": "uuid",
            "title": "Plan Id",
            "description": "Id (uuid) of the budget (`GET /v1/plans/{plan_id}`)."
          },
          "version_id": {
            "type": "string",
            "format": "uuid",
            "title": "Version Id",
            "description": "Id (uuid) of the approved version."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Name of the budget."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year the budget is for."
          },
          "number": {
            "type": "integer",
            "title": "Number",
            "description": "The version number."
          }
        },
        "type": "object",
        "required": [
          "plan_id",
          "version_id",
          "name",
          "fiscal_year",
          "number"
        ],
        "title": "BudgetVersionRef"
      },
      "BusinessHours": {
        "properties": {
          "days": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "maxItems": 7,
            "minItems": 1,
            "title": "Days",
            "description": "ISO weekdays the clock runs: 1 Monday ... 7 Sunday."
          },
          "start": {
            "type": "string",
            "title": "Start",
            "description": "When the working day starts, `HH:MM` where the company is."
          },
          "end": {
            "type": "string",
            "title": "End",
            "description": "When it ends, `HH:MM`, after the start."
          }
        },
        "type": "object",
        "required": [
          "days",
          "start",
          "end"
        ],
        "title": "BusinessHours"
      },
      "CancelInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why; kept on the order."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "CancelInput",
        "examples": [
          {
            "reason": "Ordered from another supplier"
          }
        ]
      },
      "Candidate": {
        "properties": {
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "Id of the open document; null for a booked payment (`kind` `payment`)."
          },
          "payment_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Id",
            "description": "For a booked payment (`kind` `payment`): its id. Link the line to it with `POST /v1/bank-lines/{line_id}/link`: the payment is not booked again."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Our document number, e.g. `INV-2026-000001`, or the payment's, e.g. `PAY-2026-000003`."
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number",
            "description": "The counterparty's own number (a vendor's invoice number)."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "Document kind: `sales_invoice`, `purchase_credit_note`, `purchase_bill` or `sales_credit_note`; `payment` for a payment already booked from the line's bank account that no bank line settles yet; `return` for an outgoing payment the bank executed that a credit line may return (linking it reverses the payment)."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Customer or vendor name."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Customer or vendor code, e.g. `C-DE`."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date, ISO 8601; a booked payment's payment date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Document currency: the line's, or another one (a EUR invoice paid into a CHF account, ADR-0054)."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "Amount still open, a decimal string in the document currency; for a booked payment the amount it booked on the bank account, in the line's currency."
          },
          "line_open": {
            "type": "string",
            "title": "Line Open",
            "description": "The open amount in the line's currency: `open` itself, or for a document in another currency `open` at the booking day's rate. A line within 1% of it pays the document in full; match it with the allocation's `document_amount` set to `open`.",
            "default": "0.00"
          },
          "cash_discount": {
            "type": "string",
            "title": "Cash Discount",
            "description": "Discount the line may take.",
            "default": "0.00"
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "For a booked payment in another currency than the line's: the bank's amount less the booked amount (negative when the bank took more). Matching books it as a realised exchange gain or loss; 0 otherwise.",
            "default": "0.00"
          },
          "score": {
            "type": "integer",
            "title": "Score",
            "description": "Match score: the points of the reasons, 100 structured reference or a booked payment's end-to-end id, 50 reference text, 30 exact open amount (or after discount), 25 IBAN, 15 counterparty name or a booked amount the bank converted."
          },
          "reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Reasons",
            "description": "Why the document scores: one sentence per reason."
          },
          "reason_words": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Reason Words",
            "description": "The same reasons by code (vocabulary `bankMatch.reason`) with the values they name, in the order of `reasons`: the screens word them in the person's language."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "external_number",
          "kind",
          "party",
          "party_code",
          "due_date",
          "currency",
          "open",
          "score",
          "reasons"
        ],
        "title": "Candidate"
      },
      "CapacityItemInput": {
        "properties": {
          "product": {
            "type": "string",
            "title": "Product",
            "description": "Code (or id) of the product sold by the slot: sold per unit, not goods."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code (or id) of the product's entity; needed with a code."
          },
          "slot": {
            "type": "string",
            "enum": [
              "day",
              "hour",
              "night"
            ],
            "title": "Slot",
            "description": "What one booking slot is: `night` (a hotel room), `day` (a meeting room, a person's day) or `hour` (people's time, booked in hours a day). Never changed."
          },
          "units": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Units",
            "description": "How many there are in each slot: rooms a night, seats or people a day, hours a day."
          }
        },
        "type": "object",
        "required": [
          "product",
          "slot",
          "units"
        ],
        "title": "CapacityItemInput",
        "examples": [
          {
            "entity": "CH01",
            "product": "ROOM-DBL",
            "slot": "night",
            "units": "12"
          },
          {
            "entity": "CH01",
            "product": "CONSULT",
            "slot": "hour",
            "units": "24"
          }
        ]
      },
      "CapacityItemOut": {
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Id of the product (and of the capacity item)."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Product code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Product name."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "The product's unit (`night`, `day`, `hour`, ...)."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether the product is still sold."
          },
          "slot": {
            "type": "string",
            "enum": [
              "day",
              "hour",
              "night"
            ],
            "title": "Slot",
            "description": "What one slot is: `night`, `day` or `hour`."
          },
          "units": {
            "type": "string",
            "title": "Units",
            "description": "How many there are in each slot: rooms a night, seats or people a day, hours a day."
          },
          "booked_today": {
            "type": "string",
            "title": "Booked Today",
            "description": "Units booked for today's slot."
          },
          "free_today": {
            "type": "string",
            "title": "Free Today",
            "description": "Units still free for today's slot."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who started selling it by the slot."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "product_id",
          "entity",
          "code",
          "name",
          "unit",
          "active",
          "slot",
          "units",
          "booked_today",
          "free_today",
          "created_by",
          "created_at"
        ],
        "title": "CapacityItemOut"
      },
      "CapacityItemUpdate": {
        "properties": {
          "units": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Units",
            "description": "How many there are in each slot: rooms a night, seats or people a day, hours a day. Refused below what is booked on a day from today on."
          }
        },
        "type": "object",
        "required": [
          "units"
        ],
        "title": "CapacityItemUpdate",
        "examples": [
          {
            "units": "14"
          }
        ]
      },
      "CaptureResult": {
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "einvoice",
              "model"
            ],
            "title": "Source",
            "description": "einvoice: booked from structured XML, no model call.",
            "default": "model"
          },
          "status": {
            "type": "string",
            "enum": [
              "needs_review",
              "not_an_invoice",
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "`pending_approval` (bill drafted, waits for a person), `posted`, `not_an_invoice` or `needs_review` (nothing booked)."
          },
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id (uuid) of the stored source file."
          },
          "bill_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bill Id",
            "description": "Id (uuid) of the draft bill; null when none was made."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "Id (uuid) of the approval request; null when none was made."
          },
          "vendor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VendorMatch"
              },
              {
                "type": "null"
              }
            ],
            "description": "The vendor the bill was assigned to; null when none."
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Gross total of the bill in its currency; null when none."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Currency of the bill, ISO 4217; null when none."
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "description": "0 to 1: the model's confidence in the extraction."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "What to check before approving, e.g. totals that do not tie."
          },
          "extracted": {
            "$ref": "#/components/schemas/ExtractedBill",
            "description": "What the model read from the file."
          },
          "einvoice": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EInvoiceResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The e-invoice check result, for `einvoice` captures; else null."
          }
        },
        "type": "object",
        "required": [
          "status",
          "document_id",
          "confidence",
          "warnings",
          "extracted"
        ],
        "title": "CaptureResult"
      },
      "CardInput": {
        "properties": {
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code (or id) of the company it is for, e.g. `CH01`; default: the organization's only company, else the one the person's last expense was for."
          },
          "holder": {
            "type": "string",
            "title": "Holder",
            "description": "Who holds it: the person's e-mail address or id (`user:<id>`)."
          },
          "last_four": {
            "type": "string",
            "pattern": "^[0-9]{4}$",
            "title": "Last Four",
            "description": "The card number's last four digits."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Its currency; default the company's."
          }
        },
        "type": "object",
        "required": [
          "holder",
          "last_four"
        ],
        "title": "CardInput",
        "examples": [
          {
            "entity": "CH01",
            "holder": "anna@example.com",
            "last_four": "4821"
          }
        ]
      },
      "CardLineInput": {
        "properties": {
          "card": {
            "type": "string",
            "format": "uuid",
            "title": "Card",
            "description": "The card (`GET /v1/expense-cards`)."
          },
          "booked_on": {
            "type": "string",
            "format": "date",
            "title": "Booked On",
            "description": "The day the issuer lists."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Charged, in the card's currency (a refund is negative)."
          },
          "merchant": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Merchant",
            "description": "As the issuer lists it."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The issuer's id."
          }
        },
        "type": "object",
        "required": [
          "card",
          "booked_on",
          "amount",
          "merchant"
        ],
        "title": "CardLineInput",
        "examples": [
          {
            "amount": "84.50",
            "booked_on": "2026-10-21",
            "card": "3b0c8f4e-6a52-4f8e-9c1c-1f0d7a2b9e10",
            "merchant": "Restaurant Krone"
          }
        ]
      },
      "CardLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the line."
          },
          "card_id": {
            "type": "string",
            "format": "uuid",
            "title": "Card Id",
            "description": "The card."
          },
          "last_four": {
            "type": "string",
            "title": "Last Four",
            "description": "Its last four digits."
          },
          "holder_name": {
            "type": "string",
            "title": "Holder Name",
            "description": "Its holder."
          },
          "booked_on": {
            "type": "string",
            "format": "date",
            "title": "Booked On",
            "description": "The day the issuer lists."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Charged, in the card's currency."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The card's currency."
          },
          "merchant": {
            "type": "string",
            "title": "Merchant",
            "description": "As the issuer lists it."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The issuer's id."
          },
          "expense_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expense Id",
            "description": "The expense it is; null: no receipt yet."
          },
          "expense_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expense Number",
            "description": "That expense's number."
          }
        },
        "type": "object",
        "required": [
          "id",
          "card_id",
          "last_four",
          "holder_name",
          "booked_on",
          "amount",
          "currency",
          "merchant",
          "reference",
          "expense_id",
          "expense_number"
        ],
        "title": "CardLineOut"
      },
      "CardLinesInput": {
        "properties": {
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CardLineInput"
            },
            "type": "array",
            "maxItems": 5000,
            "minItems": 1,
            "title": "Lines",
            "description": "The payments, as the issuer lists them."
          }
        },
        "type": "object",
        "required": [
          "lines"
        ],
        "title": "CardLinesInput",
        "examples": [
          {
            "lines": [
              {
                "amount": "84.50",
                "booked_on": "2026-10-21",
                "card": "3b0c8f4e-6a52-4f8e-9c1c-1f0d7a2b9e10",
                "merchant": "Restaurant Krone"
              }
            ]
          }
        ]
      },
      "CardLinesResult": {
        "properties": {
          "added": {
            "type": "integer",
            "title": "Added",
            "description": "Lines added."
          },
          "already_there": {
            "type": "integer",
            "title": "Already There",
            "description": "Lines a statement read before already had."
          },
          "matched": {
            "type": "integer",
            "title": "Matched",
            "description": "Lines matched to a receipt at once."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CardLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines added."
          }
        },
        "type": "object",
        "required": [
          "added",
          "already_there",
          "matched",
          "lines"
        ],
        "title": "CardLinesResult"
      },
      "CardOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the card."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "holder": {
            "type": "string",
            "title": "Holder",
            "description": "Its holder (`user:<id>`)."
          },
          "holder_name": {
            "type": "string",
            "title": "Holder Name",
            "description": "Their name."
          },
          "last_four": {
            "type": "string",
            "title": "Last Four",
            "description": "The last four digits."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its currency."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "The card's account with its issuer, as a vendor."
          },
          "vendor_status": {
            "type": "string",
            "title": "Vendor Status",
            "description": "That vendor's status."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Still used."
          },
          "open_lines": {
            "type": "integer",
            "title": "Open Lines",
            "description": "Its payments without a receipt yet."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "holder",
          "holder_name",
          "last_four",
          "currency",
          "vendor",
          "vendor_status",
          "active",
          "open_lines"
        ],
        "title": "CardOut"
      },
      "CardUpdate": {
        "properties": {
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "False: the card is no longer used."
          }
        },
        "type": "object",
        "required": [
          "active"
        ],
        "title": "CardUpdate",
        "examples": [
          {
            "active": false
          }
        ]
      },
      "CarryingRow": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The entity's functional currency."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "What the books of the entity hold towards the partner on the group accounts at the day, in its functional currency: receivables positive, payables negative. For information; the revaluation moves it, the reconciliation does not."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "functional_currency",
          "balance"
        ],
        "title": "CarryingRow"
      },
      "CaseDetail": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The case's id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number, CASE-000001."
          },
          "queue": {
            "type": "string",
            "title": "Queue",
            "description": "Code of the queue."
          },
          "queue_name": {
            "type": "string",
            "title": "Queue Name",
            "description": "Name of the queue."
          },
          "subject": {
            "type": "string",
            "title": "Subject",
            "description": "What it is about."
          },
          "status": {
            "type": "string",
            "enum": [
              "closed",
              "open",
              "waiting"
            ],
            "title": "Status",
            "description": "`open`, `waiting` (on the customer) or `closed`."
          },
          "priority": {
            "type": "string",
            "enum": [
              "high",
              "low",
              "normal",
              "urgent"
            ],
            "title": "Priority",
            "description": "`low`, `normal`, `high` or `urgent`."
          },
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "phone",
              "web"
            ],
            "title": "Channel",
            "description": "How it came in: `email`, `phone`, `web` or `other`."
          },
          "party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Code",
            "description": "Code of the customer."
          },
          "party_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Name",
            "description": "Name of the customer."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "Id of the person at the customer."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Their name."
          },
          "requester_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Name",
            "description": "Who asked, when not a contact."
          },
          "requester_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Email",
            "description": "Their address, where replies go."
          },
          "assignee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who works it; none: nobody yet."
          },
          "first_response": {
            "$ref": "#/components/schemas/SlaOut",
            "description": "The service level for the first reply."
          },
          "resolution": {
            "$ref": "#/components/schemas/SlaOut",
            "description": "The service level for the resolution."
          },
          "breached": {
            "type": "boolean",
            "title": "Breached",
            "description": "A service level is breached."
          },
          "resolution_note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolution Note",
            "description": "How it was resolved."
          },
          "drafts": {
            "type": "integer",
            "title": "Drafts",
            "description": "Replies drafted and not sent yet."
          },
          "last_message_at": {
            "type": "string",
            "format": "date-time",
            "title": "Last Message At",
            "description": "When the last message came or went (UTC)."
          },
          "closed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed At",
            "description": "When it was closed (UTC)."
          },
          "closed_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed By",
            "description": "Who closed it (actor object)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who opened it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          },
          "messages": {
            "items": {
              "$ref": "#/components/schemas/MessageOut"
            },
            "type": "array",
            "title": "Messages",
            "description": "What was said, the oldest first."
          },
          "recipients": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recipients",
            "description": "The addresses a reply may go to."
          },
          "sending_configured": {
            "type": "boolean",
            "title": "Sending Configured",
            "description": "Replies can be e-mailed from here (false in a test copy, or without a mail server: record a reply sent elsewhere)."
          },
          "test_copy": {
            "type": "boolean",
            "title": "Test Copy",
            "description": "This is a test copy: it never sends e-mail."
          },
          "customer_context": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CustomerContext"
              },
              {
                "type": "null"
              }
            ],
            "description": "Cross-function context (open/overdue invoices, active subscriptions, open opportunities) when the case is linked to a customer."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "queue",
          "queue_name",
          "subject",
          "status",
          "priority",
          "channel",
          "party_id",
          "party_code",
          "party_name",
          "contact_id",
          "contact_name",
          "requester_name",
          "requester_email",
          "assignee",
          "first_response",
          "resolution",
          "breached",
          "resolution_note",
          "drafts",
          "last_message_at",
          "closed_at",
          "closed_by",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at",
          "messages",
          "recipients",
          "sending_configured",
          "test_copy"
        ],
        "title": "CaseDetail",
        "examples": [
          {
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "number": "CASE-000001"
          }
        ]
      },
      "CaseInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company."
          },
          "queue": {
            "type": "string",
            "title": "Queue",
            "description": "Code (or id) of the queue."
          },
          "subject": {
            "type": "string",
            "maxLength": 300,
            "minLength": 1,
            "title": "Subject",
            "description": "What it is about."
          },
          "description": {
            "type": "string",
            "maxLength": 100000,
            "minLength": 1,
            "title": "Description",
            "description": "What the customer asked, as they said it."
          },
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "phone",
              "web"
            ],
            "title": "Channel",
            "description": "How it came in.",
            "default": "phone"
          },
          "priority": {
            "type": "string",
            "enum": [
              "high",
              "low",
              "normal",
              "urgent"
            ],
            "title": "Priority",
            "description": "Its priority.",
            "default": "normal"
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the customer."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "The person at the customer (`GET /v1/contacts`)."
          },
          "requester_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Name",
            "description": "Who asked, when they are not a contact yet."
          },
          "requester_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Email",
            "description": "Their e-mail address, which replies go to."
          },
          "assignee_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assignee User Id",
            "description": "Who works it (`GET /v1/people`); none: the queue assigns."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "queue",
          "subject",
          "description"
        ],
        "title": "CaseInput",
        "examples": [
          {
            "channel": "phone",
            "description": "Ms Muster called: the invoice went to their old address.",
            "entity": "CH01",
            "party": "C-CH",
            "priority": "normal",
            "queue": "SUPPORT",
            "subject": "Invoice 2026-0042 shows the wrong address"
          }
        ]
      },
      "CaseOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The case's id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number, CASE-000001."
          },
          "queue": {
            "type": "string",
            "title": "Queue",
            "description": "Code of the queue."
          },
          "queue_name": {
            "type": "string",
            "title": "Queue Name",
            "description": "Name of the queue."
          },
          "subject": {
            "type": "string",
            "title": "Subject",
            "description": "What it is about."
          },
          "status": {
            "type": "string",
            "enum": [
              "closed",
              "open",
              "waiting"
            ],
            "title": "Status",
            "description": "`open`, `waiting` (on the customer) or `closed`."
          },
          "priority": {
            "type": "string",
            "enum": [
              "high",
              "low",
              "normal",
              "urgent"
            ],
            "title": "Priority",
            "description": "`low`, `normal`, `high` or `urgent`."
          },
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "phone",
              "web"
            ],
            "title": "Channel",
            "description": "How it came in: `email`, `phone`, `web` or `other`."
          },
          "party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Code",
            "description": "Code of the customer."
          },
          "party_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Name",
            "description": "Name of the customer."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "Id of the person at the customer."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Their name."
          },
          "requester_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Name",
            "description": "Who asked, when not a contact."
          },
          "requester_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Email",
            "description": "Their address, where replies go."
          },
          "assignee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who works it; none: nobody yet."
          },
          "first_response": {
            "$ref": "#/components/schemas/SlaOut",
            "description": "The service level for the first reply."
          },
          "resolution": {
            "$ref": "#/components/schemas/SlaOut",
            "description": "The service level for the resolution."
          },
          "breached": {
            "type": "boolean",
            "title": "Breached",
            "description": "A service level is breached."
          },
          "resolution_note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolution Note",
            "description": "How it was resolved."
          },
          "drafts": {
            "type": "integer",
            "title": "Drafts",
            "description": "Replies drafted and not sent yet."
          },
          "last_message_at": {
            "type": "string",
            "format": "date-time",
            "title": "Last Message At",
            "description": "When the last message came or went (UTC)."
          },
          "closed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed At",
            "description": "When it was closed (UTC)."
          },
          "closed_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed By",
            "description": "Who closed it (actor object)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who opened it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "queue",
          "queue_name",
          "subject",
          "status",
          "priority",
          "channel",
          "party_id",
          "party_code",
          "party_name",
          "contact_id",
          "contact_name",
          "requester_name",
          "requester_email",
          "assignee",
          "first_response",
          "resolution",
          "breached",
          "resolution_note",
          "drafts",
          "last_message_at",
          "closed_at",
          "closed_by",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "CaseOut",
        "examples": [
          {
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "number": "CASE-000001"
          }
        ]
      },
      "CaseUpdate": {
        "properties": {
          "subject": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 300,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject",
            "description": "What it is about."
          },
          "queue": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Queue",
            "description": "Code (or id) of another queue."
          },
          "priority": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "high",
                  "low",
                  "normal",
                  "urgent"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Priority",
            "description": "`low`, `normal`, `high` or `urgent`; sets the due times anew."
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the customer."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "A person at the customer."
          },
          "requester_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Name",
            "description": "Who asked, when not a contact."
          },
          "requester_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requester Email",
            "description": "Their e-mail address."
          },
          "assignee_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Assignee User Id",
            "description": "Who works it."
          }
        },
        "type": "object",
        "title": "CaseUpdate",
        "description": "What changes; a field sent as null is cleared (the customer, contact, requester, person).",
        "examples": [
          {
            "party": "C-DE",
            "priority": "high"
          }
        ]
      },
      "CashFlowAccount": {
        "properties": {
          "account_id": {
            "type": "string",
            "format": "uuid",
            "title": "Account Id",
            "description": "Id (uuid) of the account."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Account code, e.g. `1100`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What the account adds to the line: positive brings cash in, negative takes it out (a receivable that grows is negative), in the functional currency."
          }
        },
        "type": "object",
        "required": [
          "account_id",
          "code",
          "name",
          "amount"
        ],
        "title": "CashFlowAccount"
      },
      "CashFlowLine": {
        "properties": {
          "line": {
            "type": "string",
            "title": "Line",
            "description": "The line, e.g. `op.profit`, `op.receivables`, `inv.fixed_assets`, `fin.borrowings` or `fx.cash` (the prefix is the section)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Cash in (positive) or out (negative) on the line."
          },
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/CashFlowAccount"
            },
            "type": "array",
            "title": "Accounts",
            "description": "The accounts the line is made of, by code, so it can be followed to their entries (`GET /v1/entities/{entity}/reports/general-ledger`); empty in a group's."
          },
          "report_lines": {
            "items": {
              "$ref": "#/components/schemas/CashFlowReportLine"
            },
            "type": "array",
            "title": "Report Lines",
            "description": "In a group's statement, the report lines the line is made of; empty in an entity's."
          }
        },
        "type": "object",
        "required": [
          "line",
          "amount"
        ],
        "title": "CashFlowLine"
      },
      "CashFlowReportLine": {
        "properties": {
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The group report line, e.g. `bs.assets.current.receivables`."
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Labels",
            "description": "What the group statements call the line, by language (`en`, `de`, `fr`, `it`, `sv`)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What the report line adds to the line, as `amount` above."
          }
        },
        "type": "object",
        "required": [
          "report_line",
          "labels",
          "amount"
        ],
        "title": "CashFlowReportLine"
      },
      "CashFlowSection": {
        "properties": {
          "section": {
            "type": "string",
            "enum": [
              "financing",
              "fx",
              "investing",
              "operating"
            ],
            "title": "Section",
            "description": "`operating`, `investing` or `financing` activities, or `fx`: the effect of exchange rate changes on cash held in other currencies."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "The net cash flow of the section."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CashFlowLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The section's lines in statement order."
          }
        },
        "type": "object",
        "required": [
          "section",
          "total",
          "lines"
        ],
        "title": "CashFlowSection"
      },
      "CashFlowStatement": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; all amounts are in it."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range (ISO 8601)."
          },
          "opening_cash": {
            "type": "string",
            "title": "Opening Cash",
            "description": "Cash and cash equivalents (the accounts on the balance sheet's cash line) at the start, opening balances taken over in the range included."
          },
          "sections": {
            "items": {
              "$ref": "#/components/schemas/CashFlowSection"
            },
            "type": "array",
            "title": "Sections",
            "description": "Operating, investing and financing activities, then the effect of exchange rate changes when there is one."
          },
          "net_change": {
            "type": "string",
            "title": "Net Change",
            "description": "The sum of the sections."
          },
          "closing_cash": {
            "type": "string",
            "title": "Closing Cash",
            "description": "Cash and cash equivalents at the end, per the books."
          },
          "balanced": {
            "type": "boolean",
            "title": "Balanced",
            "description": "True when the opening cash plus the net change is the closing cash."
          },
          "notes": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Notes",
            "description": "What to know when reading it (vocabulary `cashFlow.note`)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "start",
          "end",
          "opening_cash",
          "sections",
          "net_change",
          "closing_cash",
          "balanced",
          "notes"
        ],
        "title": "CashFlowStatement"
      },
      "CashForecastOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its functional currency: every total is in it."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day it was made for (the company's today)."
          },
          "opening": {
            "type": "string",
            "title": "Opening",
            "description": "The cash the books hold on that day (cash accounts)."
          },
          "weeks": {
            "items": {
              "$ref": "#/components/schemas/ForecastWeek"
            },
            "type": "array",
            "title": "Weeks",
            "description": "Thirteen weeks from this week's Monday."
          },
          "lowest": {
            "$ref": "#/components/schemas/LowestPoint",
            "description": "The least cash at a week's end."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ForecastLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "Every amount behind the weeks, by day."
          },
          "later": {
            "type": "string",
            "title": "Later",
            "description": "What open invoices and bills bring or take after the thirteenth week."
          },
          "habits": {
            "type": "integer",
            "title": "Habits",
            "description": "How many customers and vendors have a payment habit."
          },
          "changes": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ForecastChanges"
              },
              {
                "type": "null"
              }
            ],
            "description": "What changed since the forecast kept in an earlier week; null before one is."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "as_of",
          "opening",
          "weeks",
          "lowest",
          "lines",
          "later",
          "habits",
          "changes"
        ],
        "title": "CashForecastOut"
      },
      "CatchUpInput": {
        "properties": {
          "first_clean_year": {
            "type": "integer",
            "title": "First Clean Year",
            "description": "The first fiscal year that starts with its profit and loss accounts at zero. The entry is dated its first day, in its first period, which must be open."
          },
          "leave_latest_year_unappropriated": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Leave Latest Year Unappropriated",
            "description": "Whether the year before `first_clean_year` stays in the annual-result account because its general meeting is still ahead (its result is then appropriated later, like a closed year's). Default: true when that year ended less than six months before the first day of `first_clean_year`. Every earlier year goes to retained earnings."
          }
        },
        "type": "object",
        "required": [
          "first_clean_year"
        ],
        "title": "CatchUpInput",
        "examples": [
          {
            "first_clean_year": 2027,
            "leave_latest_year_unappropriated": true
          }
        ]
      },
      "CatchUpResult": {
        "properties": {
          "closes": {
            "items": {
              "$ref": "#/components/schemas/YearCloseOut"
            },
            "type": "array",
            "title": "Closes",
            "description": "The year closes the entry belongs to (kind `catch_up`): the earlier years carried forward, and the latest year when it stays unappropriated."
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "How the entry went through the approval policy."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "Things to know, e.g. a year left unappropriated."
          }
        },
        "type": "object",
        "required": [
          "closes",
          "submit",
          "warnings"
        ],
        "title": "CatchUpResult"
      },
      "ChainCheck": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity that was checked."
          },
          "entries": {
            "type": "integer",
            "title": "Entries",
            "description": "Number of posted entries in the chain."
          },
          "valid": {
            "type": "boolean",
            "title": "Valid",
            "description": "True when every entry's sequence number, previous hash and content hash check out."
          },
          "first_invalid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Invalid",
            "description": "Number of the first entry that breaks the chain; null when valid."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "`gap in chain sequence`, `previous hash mismatch` or `content hash mismatch`; null when valid."
          },
          "hash_versions": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Hash Versions",
            "description": "Entries verified per hash version (1: content; 2: every column)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "entries",
          "valid"
        ],
        "title": "ChainCheck"
      },
      "ChangeInput": {
        "properties": {
          "effective_date": {
            "type": "string",
            "format": "date",
            "title": "Effective Date",
            "description": "The first day of the lease month the new payments apply from, ISO 8601."
          },
          "payment": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Payment",
            "description": "The new payment, in the lease currency."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the payments change, e.g. an index."
          }
        },
        "type": "object",
        "required": [
          "effective_date",
          "payment",
          "reason"
        ],
        "title": "ChangeInput",
        "examples": [
          {
            "effective_date": "2027-08-01",
            "payment": "3600.00",
            "reason": "Index increase (CPI)"
          }
        ]
      },
      "Chart": {
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200,
            "title": "Title",
            "description": "The chart's title, in the person's language."
          },
          "kind": {
            "type": "string",
            "enum": [
              "bar",
              "line"
            ],
            "title": "Kind",
            "description": "`line` for a balance or a value over time, `bar` for amounts per period or a comparison."
          },
          "categories": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 60,
            "minItems": 1,
            "title": "Categories",
            "description": "The labels along the axis, e.g. months `2026-01` .. `2026-10`."
          },
          "series": {
            "items": {
              "$ref": "#/components/schemas/ChartSeries"
            },
            "type": "array",
            "maxItems": 8,
            "minItems": 1,
            "title": "Series",
            "description": "The lines or bars, one per series."
          },
          "unit": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 8
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit",
            "description": "A currency code (`CHF`) for amounts, `%` for percentages, `days`, or null."
          },
          "unverified": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unverified",
            "description": "Values of the chart that no tool returned in this turn; to be checked."
          }
        },
        "type": "object",
        "required": [
          "title",
          "kind",
          "categories",
          "series"
        ],
        "title": "Chart"
      },
      "ChartSeries": {
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 120,
            "title": "Label",
            "description": "What the series is, e.g. `Unearned revenue`."
          },
          "values": {
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "array",
            "title": "Values",
            "description": "One value per category, exactly as the tools returned it; null for none."
          }
        },
        "type": "object",
        "required": [
          "label",
          "values"
        ],
        "title": "ChartSeries"
      },
      "ChartTemplate": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "The value of `chart` when an entity is created, e.g. `ch_kmu`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What the chart is."
          },
          "countries": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Countries",
            "description": "The countries (ISO 3166-1 alpha-2) whose standard chart it is; empty for the generic chart, which every other country starts from."
          },
          "standard": {
            "type": "boolean",
            "title": "Standard",
            "description": "True for the chart a new entity of the asked `country` starts from.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "countries"
        ],
        "title": "ChartTemplate",
        "description": "A chart-of-accounts template a new entity can start from."
      },
      "Check": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Check id: `approvals`, `drafts`, `depreciation`, `fx_revaluation`, `deferred_tax`, `ar_control_reconciled`, `ap_control_reconciled`, `opening_clearing`, `bank_reconciled`, `bank_balances`, `balanced`, `integrity`, `sequence`, `year_close` (the last period of a year: its closing entry is posted), `appropriation_pending` (a closed year's result still waits for the general meeting), `recurring_generated` (recurring invoices due through the period were not made), `recurring_journals_made` (recurring journals due through the period were not posted), `subscriptions_billed` (subscription periods due through the period were not billed), `ic_reconciled` (the entity's balances with its group entities agree with theirs), `ic_interest` (the interest on its intercompany loans is accrued through the period's end), `withholding_tax_due` (the Swiss withholding tax on a dividend is paid when due), `vat_returns_filed` (the VAT returns due by the period's end are final), `revenue_recognised` (the revenue contracts' schedule lines due by the period end are recognised), `contract_position_presented` (each revenue contract's debit position is presented as an asset), `contract_control_reconciled` (the contract accounts hold no posting without a contract), `inventory_reconciled` (the stock at moving average equals the inventory accounts; a stock count of the period still open is a warning), `grni_reconciled` (the goods received not invoiced equal the GR/IR accounts; order lines still open are a warning), `close_tasks` (the organization's own close tasks of the period are done; a warning while one is open, never a failure), `payments_in_transit` (no outgoing payment dated up to the period's end waits more than 10 days for the bank to execute it, a warning) or `leases_posted` (the interest and depreciation of the active leases are booked through the period's end, a warning)."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the check verifies."
          },
          "status": {
            "type": "string",
            "enum": [
              "fail",
              "n/a",
              "pass",
              "warn"
            ],
            "title": "Status",
            "description": "`pass`, `fail` (blocks the close), `warn` (does not block) or `n/a`."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "The result in English words, e.g. the number of pending items."
          },
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "The result by a stable code (`erp.contracts.words.CLOSE_CHECKS`): the screens word it as `periodClose.result.<code>` in the person's language."
          },
          "details": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Details",
            "description": "The values the words of `code` name, by name: counts, amounts as decimal strings, days as ISO dates, lists, or reasons with their own `words`, `code`, `details` and `text`."
          }
        },
        "type": "object",
        "required": [
          "id",
          "title",
          "status",
          "detail"
        ],
        "title": "Check"
      },
      "CheckInInput": {
        "properties": {
          "room": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Room",
            "description": "The room numbers given, e.g. `204, 205`."
          }
        },
        "type": "object",
        "title": "CheckInInput",
        "examples": [
          {
            "room": "204"
          },
          {}
        ]
      },
      "CheckOutInput": {
        "properties": {
          "departure": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Departure",
            "description": "The day the guests left. Omitted: the reserved departure, or today when they leave early. A day after the reserved one books the extra nights, if free; never after today, and after the arrival."
          },
          "extras": {
            "items": {
              "$ref": "#/components/schemas/ExtraInput"
            },
            "type": "array",
            "maxItems": 100,
            "title": "Extras",
            "description": "What else goes on the invoice: breakfast, the minibar, parking."
          }
        },
        "type": "object",
        "title": "CheckOutInput",
        "examples": [
          {},
          {
            "departure": "2026-11-16",
            "extras": [
              {
                "product": "BREAKFAST",
                "quantity": 2
              }
            ]
          }
        ]
      },
      "CheckResult": {
        "properties": {
          "valid": {
            "type": "boolean",
            "title": "Valid",
            "description": "`true` when no fatal rule is broken."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Short name of what was read, e.g. `e-invoice (XRechnung 3.0 CII)`."
          },
          "profile": {
            "type": "string",
            "title": "Profile",
            "description": "The profile or specification the invoice declares."
          },
          "syntax": {
            "type": "string",
            "title": "Syntax",
            "description": "`CII` or `UBL`."
          },
          "container": {
            "type": "string",
            "title": "Container",
            "description": "`xml`, or `pdf` for a ZUGFeRD / Factur-X PDF."
          },
          "attachment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Attachment",
            "description": "For a PDF: the name of the embedded XML file."
          },
          "violations": {
            "items": {
              "$ref": "#/components/schemas/Violation"
            },
            "type": "array",
            "title": "Violations",
            "description": "The EN 16931 and XRechnung rules the invoice breaks, by rule id."
          },
          "invoice": {
            "$ref": "#/components/schemas/Invoice",
            "description": "The invoice in EN 16931 terms (parties, lines, totals, VAT breakdown)."
          }
        },
        "type": "object",
        "required": [
          "valid",
          "label",
          "profile",
          "syntax",
          "container",
          "attachment",
          "violations",
          "invoice"
        ],
        "title": "CheckResult",
        "description": "What a received e-invoice is and whether it keeps the rules (nothing stored)."
      },
      "Checklist": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`."
          },
          "period_id": {
            "type": "string",
            "format": "uuid",
            "title": "Period Id",
            "description": "Period id."
          },
          "period_status": {
            "type": "string",
            "title": "Period Status",
            "description": "`open` or `closed`."
          },
          "ready": {
            "type": "boolean",
            "title": "Ready",
            "description": "true when no check has the status `fail`."
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/Check"
            },
            "type": "array",
            "title": "Checks",
            "description": "The checks in the order evaluated."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "period",
          "period_id",
          "period_status",
          "ready",
          "checks"
        ],
        "title": "Checklist"
      },
      "CloseAction": {
        "properties": {
          "check": {
            "type": "string",
            "title": "Check",
            "description": "The close check the step belongs to (`approvals`), `vat_return`, `bank_sign_off`, or `close` for closing the period."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the person does, in English, e.g. `Approve or reject what waits for approval.`"
          },
          "ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ref",
            "description": "What the step is about where a check has several: the VAT period (`2026-Q3`) of a VAT return, the account code of a bank account."
          },
          "path": {
            "type": "string",
            "title": "Path",
            "description": "Where in the app the person does it, e.g. `/approvals`."
          }
        },
        "type": "object",
        "required": [
          "check",
          "title",
          "ref",
          "path"
        ],
        "title": "CloseAction"
      },
      "CloseInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why; kept on the order."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "CloseInput",
        "examples": [
          {
            "reason": "The supplier cannot deliver the rest"
          }
        ]
      },
      "CloseLine": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Debit in the functional currency; zero on a credit line."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Credit in the functional currency; zero on a debit line."
          }
        },
        "type": "object",
        "required": [
          "account",
          "name",
          "debit",
          "credit"
        ],
        "title": "CloseLine"
      },
      "ClosePreview": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year."
          },
          "result": {
            "type": "string",
            "title": "Result",
            "description": "The result of the year in the functional currency: a profit is positive, a loss negative. It is what the closing entry puts on the annual-result account."
          },
          "result_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Result Account",
            "description": "Code of the account with the role `annual_result`; null when the entity has none (a proposal is refused until it has)."
          },
          "result_account_suggestion": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Result Account Suggestion",
            "description": "When `result_account` is null: the code the entity's chart template gives the annual-result account (2979 in the Swiss chart, 3199 in the generic one), to add with `POST /v1/entities/{entity}/accounts` and the role `annual_result` (one person); null when the entity has the account or its template is not known."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CloseLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The closing entry: every profit and loss account with a balance brought to zero, and the result on the annual-result account."
          },
          "totals_digest": {
            "type": "string",
            "title": "Totals Digest",
            "description": "SHA-256 of the account totals the lines come from; the approval checks it again."
          },
          "date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Date",
            "description": "The date of the entry: the last day of the year; null for a year that has no periods."
          },
          "period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period",
            "description": "The period the entry is posted in, `YYYY-NN`: the year's last adjustment period when it has any, else its last regular period."
          },
          "period_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period Status",
            "description": "`open` or `closed`; the period must be open."
          },
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "cancelled",
                  "closed",
                  "pending",
                  "reopened"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "The state of the close that holds the year (`pending` or `closed`), or null when nothing holds it."
          },
          "blockers": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Blockers",
            "description": "What prevents a proposal now: drafts and entries or documents waiting for approval dated in the year, a last period that is not open, a missing annual-result account, and the period-end runs (depreciation, FX revaluation, deferred tax) of the year's last regular period that are due and not done. Empty when the year can be proposed."
          },
          "can_propose": {
            "type": "boolean",
            "title": "Can Propose",
            "description": "True when `blockers` is empty and the year is not held."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "Things to know that do not prevent the proposal."
          },
          "blocker_reasons": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Blocker Reasons",
            "description": "`blockers` by code, in the same order (`erp.contracts.words.YEAR_END`): the screens word each as `yearEnd.obstacle.<code>` from its `details`."
          },
          "warning_reasons": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Warning Reasons",
            "description": "`warnings` by code, in the same order."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "fiscal_year",
          "result",
          "result_account",
          "result_account_suggestion",
          "lines",
          "totals_digest",
          "date",
          "period",
          "period_status",
          "status",
          "blockers",
          "can_propose",
          "warnings"
        ],
        "title": "ClosePreview",
        "description": "What closing a fiscal year would post, computed now; nothing is stored."
      },
      "CloseResult": {
        "properties": {
          "close": {
            "$ref": "#/components/schemas/YearCloseOut",
            "description": "The year close as stored."
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "How the closing entry went through the approval policy: `posted` for an organization whose policy lets one person post it, else `pending_approval` with the `approval_id` a second person decides."
          }
        },
        "type": "object",
        "required": [
          "close",
          "submit"
        ],
        "title": "CloseResult"
      },
      "CloseReview": {
        "properties": {
          "period_id": {
            "type": "string",
            "format": "uuid",
            "title": "Period Id",
            "description": "Id (uuid) of the period."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "Label of the period, e.g. `2026-09`."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "memo": {
            "type": "string",
            "title": "Memo",
            "description": "The close memo in Markdown: summary, recommendation, results and actions, as the model wrote it. The stored document (`memo_document_id`) starts with a line before it: that a language model wrote it (which one) and the checklist's state."
          },
          "issues": {
            "items": {
              "$ref": "#/components/schemas/Issue"
            },
            "type": "array",
            "title": "Issues",
            "description": "The findings the agent recorded."
          },
          "memo_document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Memo Document Id",
            "description": "Id (uuid) of the stored memo document."
          },
          "ready": {
            "type": "boolean",
            "title": "Ready",
            "description": "True when the checklist is ready and no issue is a blocker."
          },
          "checklist": {
            "$ref": "#/components/schemas/Checklist",
            "description": "The close checklist after the review."
          },
          "tool_calls": {
            "items": {
              "$ref": "#/components/schemas/ToolCall"
            },
            "type": "array",
            "title": "Tool Calls",
            "description": "What the agent looked at and did."
          }
        },
        "type": "object",
        "required": [
          "period_id",
          "period",
          "entity",
          "memo",
          "issues",
          "memo_document_id",
          "ready",
          "checklist",
          "tool_calls"
        ],
        "title": "CloseReview"
      },
      "CloseReviewRequest": {
        "properties": {
          "materiality": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Materiality",
            "description": "Threshold in the entity's functional currency (decimal string) above which a variance or amount is flagged; default `1000`.",
            "default": "1000"
          },
          "run_adjustments": {
            "type": "boolean",
            "title": "Run Adjustments",
            "description": "Allow the agent to run depreciation and FX revaluation.",
            "default": true
          }
        },
        "type": "object",
        "title": "CloseReviewRequest",
        "examples": [
          {
            "materiality": "1000",
            "run_adjustments": false
          }
        ]
      },
      "CloseStatus": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`."
          },
          "period_id": {
            "type": "string",
            "format": "uuid",
            "title": "Period Id",
            "description": "Period id."
          },
          "period_end": {
            "type": "string",
            "format": "date",
            "title": "Period End",
            "description": "The period's last day: working day 0."
          },
          "period_status": {
            "type": "string",
            "title": "Period Status",
            "description": "`open` or `closed`."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day `overdue` is judged on."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who owns the close."
          },
          "ready": {
            "type": "boolean",
            "title": "Ready",
            "description": "The close checklist has no failing check."
          },
          "failing_checks": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Failing Checks",
            "description": "The ids of the checks that fail."
          },
          "done": {
            "type": "integer",
            "title": "Done",
            "description": "Steps and tasks that are done or do not apply."
          },
          "total": {
            "type": "integer",
            "title": "Total",
            "description": "Steps and tasks."
          },
          "overdue": {
            "type": "integer",
            "title": "Overdue",
            "description": "Steps and tasks that are overdue."
          },
          "steps": {
            "items": {
              "$ref": "#/components/schemas/StepStatus"
            },
            "type": "array",
            "title": "Steps",
            "description": "The steps, in the order of the close."
          },
          "tasks": {
            "items": {
              "$ref": "#/components/schemas/TaskStatus"
            },
            "type": "array",
            "title": "Tasks",
            "description": "The entity's tasks: the active ones, and an inactive one done for this period."
          },
          "job_log": {
            "items": {
              "$ref": "#/components/schemas/JobLogEntry"
            },
            "type": "array",
            "title": "Job Log",
            "description": "What the scheduled close job did for this period, the latest first (at most 60 entries)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "period",
          "period_id",
          "period_end",
          "period_status",
          "as_of",
          "owner",
          "ready",
          "failing_checks",
          "done",
          "total",
          "overdue",
          "steps",
          "tasks"
        ],
        "title": "CloseStatus",
        "examples": [
          {
            "as_of": "2026-10-02",
            "done": 4,
            "entity": "CH01",
            "failing_checks": [
              "bank_reconciled"
            ],
            "overdue": 1,
            "owner": {
              "email": "alice@example.com",
              "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "name": "Alice"
            },
            "period": "2026-09",
            "period_end": "2026-09-30",
            "period_id": "4f5e6d7c-8b9a-4c0d-9e1f-2a3b4c5d6e7f",
            "period_status": "open",
            "ready": false,
            "steps": [
              {
                "detail": "3 assets due",
                "due_date": "2026-10-01",
                "status": "done",
                "step": "depreciation",
                "title": "Depreciation run"
              }
            ],
            "tasks": [
              {
                "detail": "not done yet",
                "due_date": "2026-10-02",
                "status": "open",
                "task": {
                  "active": true,
                  "created_at": "2026-09-01T08:00:00Z",
                  "created_by": {
                    "id": "user:alice",
                    "name": "Alice",
                    "type": "human"
                  },
                  "due_day": 2,
                  "entity": "CH01",
                  "id": "8e3f4051-6273-4c84-9d95-afb6c7d8e920",
                  "title": "Reconcile the credit card account"
                }
              }
            ],
            "total": 7
          }
        ]
      },
      "CollectionCriteria": {
        "properties": {
          "collection_date": {
            "type": "string",
            "format": "date",
            "title": "Collection Date",
            "description": "When the money is to be collected (the requested collection date)."
          },
          "customers": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customers",
            "description": "Only these customers (codes); default all with a mandate."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "The EUR bank account collected into (it needs a creditor identifier); default the first EUR bank account that has one."
          }
        },
        "type": "object",
        "required": [
          "collection_date"
        ],
        "title": "CollectionCriteria",
        "examples": [
          {
            "collection_date": "2026-10-20",
            "customers": [
              "C-HH"
            ]
          }
        ]
      },
      "CollectionLine": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Invoice number."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Customer name."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Invoice date."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "Open amount in EUR."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount to collect: the open amount less the discount."
          },
          "discount": {
            "type": "string",
            "title": "Discount",
            "description": "Cash discount (Skonto) taken: the invoice's terms, when the collection date is within its discount period."
          },
          "mandate_id": {
            "type": "string",
            "format": "uuid",
            "title": "Mandate Id",
            "description": "The mandate collected under."
          },
          "mandate_reference": {
            "type": "string",
            "title": "Mandate Reference",
            "description": "Its reference."
          },
          "scheme": {
            "type": "string",
            "enum": [
              "B2B",
              "CORE"
            ],
            "title": "Scheme",
            "description": "`CORE` or `B2B`."
          },
          "sequence_type": {
            "type": "string",
            "enum": [
              "FNAL",
              "FRST",
              "OOFF",
              "RCUR"
            ],
            "title": "Sequence Type",
            "description": "`RCUR` or `OOFF`."
          },
          "prenotified_on": {
            "type": "string",
            "format": "date",
            "title": "Prenotified On",
            "description": "The day the customer was told of the collection: the invoice date."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "customer",
          "customer_name",
          "document_date",
          "due_date",
          "open",
          "amount",
          "discount",
          "mandate_id",
          "mandate_reference",
          "scheme",
          "sequence_type",
          "prenotified_on"
        ],
        "title": "CollectionLine"
      },
      "CollectionProposal": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "collection_date": {
            "type": "string",
            "format": "date",
            "title": "Collection Date",
            "description": "The requested collection date."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "The bank account collected into."
          },
          "creditor_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditor Id",
            "description": "Its SEPA creditor identifier."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CollectionLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The invoices proposed: due by the collection date, or within their cash discount period."
          },
          "skipped": {
            "items": {
              "$ref": "#/components/schemas/SkippedInvoice"
            },
            "type": "array",
            "title": "Skipped",
            "description": "Invoices due of customers with a mandate that are not proposed, and why."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Sum of the amounts proposed."
          },
          "problems": {
            "items": {
              "$ref": "#/components/schemas/BlockerOut"
            },
            "type": "array",
            "title": "Problems",
            "description": "What stops collecting at all (no account with a creditor identifier)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "collection_date",
          "bank_account",
          "creditor_id",
          "lines",
          "skipped",
          "total",
          "problems"
        ],
        "title": "CollectionProposal"
      },
      "CollectionRow": {
        "properties": {
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "title": "Payment Id",
            "description": "Id of the receipt."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Receipt number: the end-to-end id in the file."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Customer name."
          },
          "mandate_id": {
            "type": "string",
            "format": "uuid",
            "title": "Mandate Id",
            "description": "The mandate."
          },
          "mandate_reference": {
            "type": "string",
            "title": "Mandate Reference",
            "description": "Its reference."
          },
          "scheme": {
            "type": "string",
            "enum": [
              "B2B",
              "CORE"
            ],
            "title": "Scheme",
            "description": "`CORE` or `B2B`."
          },
          "sequence_type": {
            "type": "string",
            "enum": [
              "FNAL",
              "FRST",
              "OOFF",
              "RCUR"
            ],
            "title": "Sequence Type",
            "description": "`RCUR` or `OOFF`."
          },
          "collection_date": {
            "type": "string",
            "format": "date",
            "title": "Collection Date",
            "description": "Requested collection date (receipt date)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Always `EUR`."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Receipt status: `posted`, `pending_approval`, `reversed`."
          },
          "bank_account": {
            "type": "string",
            "title": "Bank Account",
            "description": "The bank account collected into."
          },
          "bank_status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "executed",
                  "in_transit"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Status",
            "description": "`in_transit` until a bank line shows the money arrived, then `executed`."
          },
          "export": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExportInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "The pain.008 file it was sent in, if any."
          },
          "problems": {
            "items": {
              "$ref": "#/components/schemas/BlockerOut"
            },
            "type": "array",
            "title": "Problems",
            "description": "What stops releasing it now."
          },
          "bank_refusal": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BankRefusal"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the bank rejected it or the debtor's bank returned it."
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "number",
          "customer",
          "customer_name",
          "mandate_id",
          "mandate_reference",
          "scheme",
          "sequence_type",
          "collection_date",
          "amount",
          "currency",
          "status",
          "bank_account",
          "bank_status",
          "export",
          "problems"
        ],
        "title": "CollectionRow"
      },
      "CollectionRunInput": {
        "properties": {
          "collection_date": {
            "type": "string",
            "format": "date",
            "title": "Collection Date",
            "description": "The requested collection date."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "The EUR bank account collected into (see the proposal)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CollectionRunLine"
            },
            "type": "array",
            "maxItems": 5000,
            "minItems": 1,
            "title": "Lines",
            "description": "The invoices to collect, each once."
          }
        },
        "type": "object",
        "required": [
          "collection_date",
          "lines"
        ],
        "title": "CollectionRunInput",
        "examples": [
          {
            "collection_date": "2026-10-20",
            "lines": [
              {
                "amount": "5000.00",
                "document": "INV-2026-000003"
              }
            ]
          }
        ]
      },
      "CollectionRunLine": {
        "properties": {
          "document": {
            "type": "string",
            "title": "Document",
            "description": "Invoice id or number."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Amount to collect, at most the open amount."
          },
          "discount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Discount",
            "description": "Cash discount taken (see the proposal): only within the invoice's discount period, at most its terms.",
            "default": "0"
          }
        },
        "type": "object",
        "required": [
          "document",
          "amount"
        ],
        "title": "CollectionRunLine"
      },
      "CollectionRunResult": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "collection_date": {
            "type": "string",
            "format": "date",
            "title": "Collection Date",
            "description": "The requested collection date."
          },
          "collections": {
            "items": {
              "$ref": "#/components/schemas/RunCollection"
            },
            "type": "array",
            "title": "Collections",
            "description": "One receipt per mandate."
          },
          "posted": {
            "type": "integer",
            "title": "Posted",
            "description": "How many are posted."
          },
          "pending_approval": {
            "type": "integer",
            "title": "Pending Approval",
            "description": "How many wait for approval."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "collection_date",
          "collections",
          "posted",
          "pending_approval"
        ],
        "title": "CollectionRunResult"
      },
      "CompanyDone": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The code of the company created."
          },
          "standard": {
            "type": "string",
            "title": "Standard",
            "description": "The accounting standard it reports under."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency of its books."
          },
          "chart": {
            "type": "string",
            "title": "Chart",
            "description": "The chart template its accounts were copied from."
          },
          "framework": {
            "type": "string",
            "title": "Framework",
            "description": "Its accounting framework."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year whose periods were opened."
          },
          "tax_settings": {
            "type": "boolean",
            "title": "Tax Settings",
            "description": "True when its tax settings (method and return period) were saved; false where the country has none to set (US sales tax) or keeps the defaults (Liechtenstein).",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "entity",
          "standard",
          "currency",
          "chart",
          "framework",
          "fiscal_year"
        ],
        "title": "CompanyDone"
      },
      "CompanyFinish": {
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 4000,
            "minLength": 1,
            "title": "Code",
            "description": "The `code` the provider sent the browser back with.",
            "examples": [
              "c0d3-from-the-provider"
            ]
          },
          "state": {
            "type": "string",
            "maxLength": 4000,
            "minLength": 1,
            "title": "State",
            "description": "The `state` the provider sent the browser back with.",
            "examples": [
              "eyJjIjoi.c2lnbmF0dXJl"
            ]
          }
        },
        "type": "object",
        "required": [
          "code",
          "state"
        ],
        "title": "CompanyFinish",
        "examples": [
          {
            "code": "c0d3-from-the-provider",
            "state": "eyJjIjoi.c2lnbmF0dXJl"
          }
        ]
      },
      "CompanyInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "The company's legal name."
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Z]{2}$",
            "title": "Country",
            "description": "Where it is registered (`GET /v1/setup/options`)."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "The state (US) or province (Canada), ISO 3166-2; required there, refused elsewhere."
          },
          "standard": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Standard",
            "description": "The accounting standard's id, one of the country's. Omitted: the country's first (`GET /v1/setup/options` lists them, the default first)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The currency of the books, one the country allows. Cannot be changed later. Omitted: the country's currency."
          },
          "fiscal_year_start_month": {
            "type": "integer",
            "maximum": 12.0,
            "minimum": 1.0,
            "title": "Fiscal Year Start Month",
            "description": "The month the fiscal year starts, 1 to 12.",
            "default": 1
          },
          "tax_period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Period",
            "description": "The tax return period, one of the country's; default: its first."
          },
          "tax_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Number",
            "description": "The tax registration number, when asked."
          },
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Number."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town."
          },
          "industry": {
            "type": "string",
            "enum": [
              "ecommerce",
              "general",
              "hospitality",
              "manufacturing",
              "retail",
              "services",
              "trade"
            ],
            "title": "Industry",
            "description": "The company's industry (`GET /v1/industries`): `general`, `hospitality`, `services`, `trade`, `retail`, `ecommerce` or `manufacturing`. It puts the screens of the industry first in the app's menu and on its Home; it switches nothing off, and every operation works the same in every industry. Default `general`; it can be changed later.",
            "default": "general"
          },
          "code": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]{2,20}$",
            "title": "Code",
            "description": "Short unique code, 2 to 20 characters of A-Z, 0-9, `_` and `-`, e.g. `CH02`; it names the company in every URL."
          }
        },
        "type": "object",
        "required": [
          "name",
          "country",
          "code"
        ],
        "title": "CompanyInput",
        "description": "The setup wizard's answers for a further company of an organization that has one.",
        "examples": [
          {
            "code": "CH02",
            "country": "CH",
            "currency": "CHF",
            "fiscal_year_start_month": 1,
            "name": "Muster Services AG",
            "standard": "ch_co",
            "tax_number": "CHE-123.456.788 MWST",
            "tax_period": "quarter"
          }
        ]
      },
      "CompanySignInSetup": {
        "properties": {
          "available": {
            "type": "boolean",
            "title": "Available",
            "description": "Whether company sign-in can be set up on this server (it needs the key that seals client secrets and the address people reach the app at)."
          },
          "redirect_uri": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redirect Uri",
            "description": "The sign-in redirect URI to register in the app at the identity provider."
          },
          "connection": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ConnectionOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The connection; null: none yet."
          }
        },
        "type": "object",
        "required": [
          "available",
          "redirect_uri",
          "connection"
        ],
        "title": "CompanySignInSetup"
      },
      "CompanyStart": {
        "properties": {
          "email": {
            "type": "string",
            "maxLength": 320,
            "minLength": 3,
            "title": "Email",
            "description": "The person's address: its domain names their organization's provider.",
            "examples": [
              "lena.meier@acme.com"
            ]
          },
          "org_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Org Id",
            "description": "The organization to sign in to, when the address may sign in to several through their company's provider."
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "CompanyStart",
        "examples": [
          {
            "email": "lena.meier@acme.com"
          }
        ]
      },
      "CompanyStartOut": {
        "properties": {
          "url": {
            "type": "string",
            "title": "Url",
            "description": "The identity provider's sign-in page: the browser goes there, and comes back to the redirect URI with `code` and `state`."
          }
        },
        "type": "object",
        "required": [
          "url"
        ],
        "title": "CompanyStartOut"
      },
      "Comparative": {
        "properties": {
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The comparative figure (prior year, comparative date or budget), signed as `balance`: a normal balance is positive."
          },
          "change": {
            "type": "string",
            "title": "Change",
            "description": "This report's figure less `amount`; for a budget, the variance."
          },
          "change_pct": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Change Pct",
            "description": "`change` as a percent of `amount` (of its absolute value), one decimal; null when `amount` is zero."
          }
        },
        "type": "object",
        "required": [
          "amount",
          "change",
          "change_pct"
        ],
        "title": "Comparative"
      },
      "Comparison": {
        "properties": {
          "plan_id": {
            "type": "string",
            "format": "uuid",
            "title": "Plan Id",
            "description": "The plan."
          },
          "version_id": {
            "type": "string",
            "format": "uuid",
            "title": "Version Id",
            "description": "The version compared."
          },
          "version_status": {
            "type": "string",
            "enum": [
              "approved",
              "draft",
              "submitted",
              "superseded"
            ],
            "title": "Version Status",
            "description": "Its status."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency of every amount."
          },
          "by": {
            "type": "string",
            "enum": [
              "account",
              "report_line"
            ],
            "title": "By",
            "description": "`account` or `report_line`."
          },
          "against": {
            "type": "string",
            "enum": [
              "actuals",
              "version"
            ],
            "title": "Against",
            "description": "`actuals`, or `version` when compared with another plan version too.",
            "default": "actuals"
          },
          "against_version_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Against Version Id",
            "description": "The version compared against (`against_version`)."
          },
          "periods": {
            "items": {
              "$ref": "#/components/schemas/ComparisonPeriod"
            },
            "type": "array",
            "title": "Periods",
            "description": "The periods compared, in order."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/ComparisonRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "Revenue first, then expenses, each by key: every account (or report line) with a plan or an actual in the periods."
          },
          "revenue": {
            "$ref": "#/components/schemas/ComparisonRow",
            "description": "The revenue rows added up."
          },
          "expenses": {
            "$ref": "#/components/schemas/ComparisonRow",
            "description": "The expense rows added up."
          },
          "net": {
            "$ref": "#/components/schemas/ComparisonRow",
            "description": "Revenue less expenses (`type` is `revenue`: more is good news)."
          }
        },
        "type": "object",
        "required": [
          "plan_id",
          "version_id",
          "version_status",
          "entity",
          "currency",
          "by",
          "periods",
          "rows",
          "revenue",
          "expenses",
          "net"
        ],
        "title": "Comparison"
      },
      "ComparisonCell": {
        "properties": {
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`."
          },
          "plan": {
            "type": "string",
            "title": "Plan",
            "description": "The planned amount."
          },
          "actual": {
            "type": "string",
            "title": "Actual",
            "description": "What was posted: the period's entries (and those of the year's adjustment periods, counted in its last regular period), closing entries left out, in the natural direction."
          },
          "against": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Against",
            "description": "With `against_version`: that version's amount; empty otherwise."
          },
          "variance": {
            "type": "string",
            "title": "Variance",
            "description": "Actual less plan; with `against_version`, this version's amount less that version's."
          },
          "variance_pct": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Variance Pct",
            "description": "Variance as a percent of the plan (with `against_version`, of that version's amount), one decimal; empty when that is zero."
          },
          "favourable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Favourable",
            "description": "True when the variance is good news (more revenue, fewer expenses); empty when it is zero."
          }
        },
        "type": "object",
        "required": [
          "period",
          "plan",
          "actual",
          "variance",
          "variance_pct",
          "favourable"
        ],
        "title": "ComparisonCell"
      },
      "ComparisonPeriod": {
        "properties": {
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "First day."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "Last day."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`open` or `closed`: an open period's actuals are not final yet."
          }
        },
        "type": "object",
        "required": [
          "period",
          "start_date",
          "end_date",
          "status"
        ],
        "title": "ComparisonPeriod"
      },
      "ComparisonRange": {
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "previous",
              "year_ago"
            ],
            "title": "Mode",
            "description": "`previous` or `year_ago`, as requested."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the comparison range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the comparison range (ISO 8601)."
          }
        },
        "type": "object",
        "required": [
          "mode",
          "start",
          "end"
        ],
        "title": "ComparisonRange"
      },
      "ComparisonRow": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "The account code, or the report line."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The account's name, or the report line again."
          },
          "type": {
            "type": "string",
            "enum": [
              "expense",
              "revenue"
            ],
            "title": "Type",
            "description": "`revenue` or `expense`."
          },
          "cells": {
            "items": {
              "$ref": "#/components/schemas/ComparisonCell"
            },
            "type": "array",
            "title": "Cells",
            "description": "One per period, in order."
          },
          "total": {
            "$ref": "#/components/schemas/ComparisonCell",
            "description": "The periods added up (`period` is `total`)."
          },
          "outlook": {
            "items": {
              "$ref": "#/components/schemas/YearOutlook"
            },
            "type": "array",
            "title": "Outlook",
            "description": "Per fiscal year of the periods compared: actuals of its closed periods plus the plan of the others."
          }
        },
        "type": "object",
        "required": [
          "key",
          "name",
          "type",
          "cells",
          "total",
          "outlook"
        ],
        "title": "ComparisonRow"
      },
      "Completion": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Completion id."
          },
          "evidence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Evidence",
            "description": "What shows it was done."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "The note."
          },
          "completed_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Completed By",
            "description": "Who did it (actor object)."
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "title": "Completed At",
            "description": "When it was recorded (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "evidence",
          "note",
          "completed_by",
          "completed_at"
        ],
        "title": "Completion"
      },
      "CompletionInput": {
        "properties": {
          "evidence": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Evidence",
            "description": "What shows it was done (a reference or a link)."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A note."
          }
        },
        "type": "object",
        "title": "CompletionInput",
        "examples": [
          {
            "evidence": "Statement 2026-09 reconciled, workpaper CC-09",
            "note": "Two items carried forward"
          }
        ]
      },
      "Connection": {
        "properties": {
          "mode": {
            "type": "string",
            "enum": [
              "http",
              "in_process"
            ],
            "title": "Mode",
            "description": "`in_process` (the reference data is loaded into the server) or `http` (a data-vNext service)."
          },
          "base_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Url",
            "description": "Address of the data-vNext service; null in process."
          },
          "pinned_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pinned Version",
            "description": "ERP_REFDATA_DATASET_VERSION, if every call is pinned."
          },
          "reachable": {
            "type": "boolean",
            "title": "Reachable",
            "description": "True when the register answered."
          },
          "dataset_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dataset Version",
            "description": "Version of the reference dataset in use; null when unknown."
          },
          "latency_ms": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Latency Ms",
            "description": "Round trip of the register."
          },
          "checked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Checked At",
            "description": "When the connection was checked (ISO 8601, UTC)."
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error",
            "description": "The last connection error; null if none."
          },
          "last_error_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error At",
            "description": "When that error happened (ISO 8601, UTC); null if none."
          }
        },
        "type": "object",
        "required": [
          "mode",
          "reachable",
          "checked_at"
        ],
        "title": "Connection"
      },
      "ConnectionInput": {
        "properties": {
          "provider": {
            "type": "string",
            "enum": [
              "entra",
              "oidc",
              "okta"
            ],
            "title": "Provider",
            "description": "The identity provider: `okta` (Okta), `entra` (Microsoft Entra ID, the former Azure AD) or `oidc` (any other OpenID Connect provider)."
          },
          "issuer": {
            "type": "string",
            "maxLength": 300,
            "minLength": 3,
            "title": "Issuer",
            "description": "Where the provider is: for Okta the Okta domain (`acme.okta.com`) or an authorization server's issuer; for Microsoft Entra ID the tenant id or the tenant's primary domain (`acme.onmicrosoft.com`); otherwise the issuer URL (`https://...`).",
            "examples": [
              "acme.okta.com"
            ]
          },
          "client_id": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Client Id",
            "description": "The client id (Entra: application id) of the app registered at the provider for this sign-in.",
            "examples": [
              "0oa1b2c3d4e5f6g7h8i9"
            ]
          },
          "client_secret": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Secret",
            "description": "The app's client secret. Left out on a change: the one kept stays; an empty string removes it (an app without a secret, which signs in with PKCE alone)."
          },
          "domains": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 20
              },
              {
                "type": "null"
              }
            ],
            "title": "Domains",
            "description": "The e-mail domains whose people sign in through it. Left out: the domain of the administrator's own address.",
            "examples": [
              [
                "acme.com"
              ]
            ]
          },
          "required": {
            "type": "boolean",
            "title": "Required",
            "description": "Whether those people may sign in only through it: Google and a password no longer open the organization for them.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "provider",
          "issuer",
          "client_id"
        ],
        "title": "ConnectionInput",
        "examples": [
          {
            "client_id": "0oa1b2c3d4e5f6g7h8i9",
            "client_secret": "s3cr3t-of-the-okta-app",
            "domains": [
              "acme.com"
            ],
            "issuer": "acme.okta.com",
            "provider": "okta",
            "required": false
          }
        ]
      },
      "ConnectionOut": {
        "properties": {
          "provider": {
            "type": "string",
            "enum": [
              "entra",
              "oidc",
              "okta"
            ],
            "title": "Provider",
            "description": "The identity provider: `okta` (Okta), `entra` (Microsoft Entra ID, the former Azure AD) or `oidc` (any other OpenID Connect provider)."
          },
          "issuer": {
            "type": "string",
            "title": "Issuer",
            "description": "The provider's issuer, which its ID tokens name and its discovery document is read from.",
            "examples": [
              "https://acme.okta.com"
            ]
          },
          "client_id": {
            "type": "string",
            "title": "Client Id",
            "description": "The client id of the app registered at the provider."
          },
          "has_secret": {
            "type": "boolean",
            "title": "Has Secret",
            "description": "Whether the app's client secret is kept (sealed; it is never shown)."
          },
          "domains": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Domains",
            "description": "The e-mail domains whose people sign in through it."
          },
          "required": {
            "type": "boolean",
            "title": "Required",
            "description": "Whether those people may sign in only through it, not with Google or a password."
          },
          "last_used_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Used At",
            "description": "The last sign-in through it (UTC)."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At",
            "description": "When it was last changed (UTC)."
          }
        },
        "type": "object",
        "required": [
          "provider",
          "issuer",
          "client_id",
          "has_secret",
          "domains",
          "required",
          "last_used_at",
          "updated_at"
        ],
        "title": "ConnectionOut"
      },
      "ConnectorAnswer": {
        "properties": {
          "redirect_to": {
            "type": "string",
            "title": "Redirect To",
            "description": "Where the browser goes next: the app's address with a one-time code (`code`, good for ten minutes), or with `error=access_denied` when refused."
          }
        },
        "type": "object",
        "required": [
          "redirect_to"
        ],
        "title": "ConnectorAnswer",
        "examples": [
          {
            "redirect_to": "https://claude.ai/api/mcp/auth_callback?code=erpcode_…&state=af0"
          }
        ]
      },
      "ConnectorDecision": {
        "properties": {
          "client_id": {
            "type": "string",
            "maxLength": 4000,
            "title": "Client Id",
            "description": "The app's client id, as it sent it."
          },
          "redirect_uri": {
            "type": "string",
            "maxLength": 2000,
            "title": "Redirect Uri",
            "description": "Where the app wants the answer."
          },
          "app_state": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "App State",
            "description": "The app's state, returned to it unchanged."
          },
          "code_challenge": {
            "type": "string",
            "maxLength": 200,
            "title": "Code Challenge",
            "description": "The PKCE challenge.",
            "default": ""
          },
          "code_challenge_method": {
            "type": "string",
            "maxLength": 20,
            "title": "Code Challenge Method",
            "description": "Must be `S256`.",
            "default": ""
          },
          "allow": {
            "type": "boolean",
            "title": "Allow",
            "description": "true allows the app; false refuses it."
          },
          "post": {
            "type": "boolean",
            "title": "Post",
            "description": "Also let it post routine entries within the approval policy.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "client_id",
          "redirect_uri",
          "allow"
        ],
        "title": "ConnectorDecision",
        "description": "The person's answer, with the app's request as it came (OAuth 2.1 authorization request).",
        "examples": [
          {
            "allow": true,
            "app_state": "af0ifjsldkj",
            "client_id": "erpapp_eyJuIjoiQ2xhdWRlIn0",
            "code_challenge": "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM",
            "code_challenge_method": "S256",
            "post": false,
            "redirect_uri": "https://claude.ai/api/mcp/auth_callback"
          }
        ]
      },
      "ConnectorRequest": {
        "properties": {
          "app_name": {
            "type": "string",
            "title": "App Name",
            "description": "The name the app registered with."
          },
          "returns_to": {
            "type": "string",
            "title": "Returns To",
            "description": "The host the person is sent back to once they answer."
          },
          "organization": {
            "type": "string",
            "title": "Organization",
            "description": "The organization the app would work in: the person's."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "What the app may always do: `read` and `draft`."
          },
          "can_post": {
            "type": "boolean",
            "title": "Can Post",
            "description": "Whether the person may also let it post (they hold `post` themselves)."
          }
        },
        "type": "object",
        "required": [
          "app_name",
          "returns_to",
          "organization",
          "scopes",
          "can_post"
        ],
        "title": "ConnectorRequest",
        "description": "What the person is asked to allow.",
        "examples": [
          {
            "app_name": "Claude",
            "can_post": true,
            "organization": "Demo AG",
            "returns_to": "claude.ai",
            "scopes": [
              "read",
              "draft"
            ]
          }
        ]
      },
      "ConsolidationRunSummary": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the run."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The group date."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "The run's number for this group and date."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "final",
              "superseded"
            ],
            "title": "Status",
            "description": "`draft`, `final` or `superseded`."
          },
          "complete": {
            "type": "boolean",
            "title": "Complete",
            "description": "True when no blocking exception was found."
          },
          "blocking": {
            "type": "integer",
            "title": "Blocking",
            "description": "Blocking exceptions."
          },
          "warnings": {
            "type": "integer",
            "title": "Warnings",
            "description": "Warnings."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it, as an actor object."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was made (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "as_of",
          "version",
          "status",
          "complete",
          "blocking",
          "warnings",
          "created_by",
          "created_at"
        ],
        "title": "ConsolidationRunSummary"
      },
      "Contact": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "BT-41 / BT-56 contact point"
          },
          "phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "BT-42 / BT-57"
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "BT-43 / BT-58"
          }
        },
        "type": "object",
        "title": "Contact"
      },
      "ContactInput": {
        "properties": {
          "first_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name",
            "description": "First name."
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Role or department, e.g. `Head of purchasing`. A role that says billing, accounting or `Buchhaltung` makes the contact one an invoice goes to by default."
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Phone number."
          },
          "mobile": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Mobile",
            "description": "Mobile number."
          },
          "last_name": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Last Name",
            "description": "Last name. A `name` sent instead is split: its last word is the last name, the words before it the first name."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company (entity)."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Code (or id) of the customer or vendor the person is at."
          },
          "kind": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "customer",
                  "vendor"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Kind",
            "description": "Needed only when `party` is a code of a customer and a vendor."
          },
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "rm",
                  "sv"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Language to write to them in (`de`, `fr`, `it`, `en`, `sv`, `rm`)."
          },
          "email_opt_out": {
            "type": "boolean",
            "title": "Email Opt Out",
            "description": "They asked not to get sales or marketing e-mails (invoices still go).",
            "default": false
          },
          "custom": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "integer"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who looks after the contact (`GET /v1/people`); omitted: you (a key or an agent: the person behind it)."
          }
        },
        "type": "object",
        "required": [
          "last_name",
          "entity",
          "party"
        ],
        "title": "ContactInput",
        "examples": [
          {
            "email": "anna.muster@kunde.example",
            "entity": "CH01",
            "first_name": "Anna",
            "language": "de",
            "last_name": "Muster",
            "party": "C-CH",
            "phone": "+41 44 123 45 67",
            "role": "Head of purchasing"
          }
        ]
      },
      "ContactMerge": {
        "properties": {
          "into": {
            "type": "string",
            "format": "uuid",
            "title": "Into",
            "description": "Id of the contact that stays (same customer or vendor)."
          }
        },
        "type": "object",
        "required": [
          "into"
        ],
        "title": "ContactMerge",
        "examples": [
          {
            "into": "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
          }
        ]
      },
      "ContactOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the contact."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer or vendor."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Its code."
          },
          "party_name": {
            "type": "string",
            "title": "Party Name",
            "description": "Its name."
          },
          "party_kind": {
            "type": "string",
            "enum": [
              "customer",
              "vendor"
            ],
            "title": "Party Kind",
            "description": "`customer` or `vendor`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "First and last name; `\"\"` once erased."
          },
          "first_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name",
            "description": "First name."
          },
          "last_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name",
            "description": "Last name; null only once erased."
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Role or department."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Phone number."
          },
          "mobile": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mobile",
            "description": "Mobile number."
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Language to write to them in (`de`, `fr`, `it`, `en`, `sv`, `rm`)."
          },
          "email_opt_out": {
            "type": "boolean",
            "title": "Email Opt Out",
            "description": "They asked not to get sales or marketing e-mails.",
            "default": false
          },
          "custom": {
            "additionalProperties": true,
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who looks after the contact."
          },
          "erased": {
            "type": "boolean",
            "title": "Erased",
            "description": "Its personal data was erased (it stays as a placeholder).",
            "default": false
          },
          "erased_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Erased At",
            "description": "When it was erased (UTC)."
          },
          "merged_into_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Merged Into Id",
            "description": "The contact it was merged into (`POST .../merge`), if any."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who added it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "party_id",
          "party_code",
          "party_name",
          "party_kind",
          "name",
          "created_by",
          "created_at"
        ],
        "title": "ContactOut",
        "examples": [
          {
            "created_at": "2026-10-23T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "custom": {},
            "email": "anna.muster@kunde.example",
            "email_opt_out": false,
            "entity": "CH01",
            "erased": false,
            "first_name": "Anna",
            "id": "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e",
            "language": "de",
            "last_name": "Muster",
            "name": "Anna Muster",
            "party_code": "C-CH",
            "party_id": "6c9d0e1f-2a3b-4c4d-9e5f-6a7b8c9d0e1f",
            "party_kind": "customer",
            "party_name": "Kunde AG",
            "phone": "+41 44 123 45 67",
            "role": "Head of purchasing"
          }
        ]
      },
      "ContactUpdate": {
        "properties": {
          "first_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name",
            "description": "`\"\"` clears."
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Role or department, e.g. `Head of purchasing`. A role that says billing, accounting or `Buchhaltung` makes the contact one an invoice goes to by default."
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Phone number."
          },
          "mobile": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Mobile",
            "description": "Mobile number."
          },
          "last_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name",
            "description": "New."
          },
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "rm",
                  "sv"
                ]
              },
              {
                "type": "string",
                "const": ""
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "`\"\"` clears."
          },
          "email_opt_out": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email Opt Out",
            "description": "New opt-out."
          },
          "custom": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    },
                    {
                      "type": "integer"
                    },
                    {
                      "type": "boolean"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "New owner (`GET /v1/people`). Someone who sees only their own or their team's records hands a contact only to one of those people."
          }
        },
        "type": "object",
        "title": "ContactUpdate",
        "description": "What changes (null or omitted: as is; `\"\"` clears a text field but the last name).",
        "examples": [
          {
            "email": "anna@kunde.example",
            "role": "CFO"
          }
        ]
      },
      "ContentGap": {
        "properties": {
          "party": {
            "type": "string",
            "enum": [
              "buyer",
              "seller"
            ],
            "title": "Party",
            "description": "Whose record lacks it: `seller` (the entity) or `buyer` (the customer)."
          },
          "field": {
            "type": "string",
            "enum": [
              "name",
              "postal_code",
              "street",
              "tax_id",
              "town",
              "vat_designation",
              "vat_number"
            ],
            "title": "Field",
            "description": "The missing field: `name`, `street`, `postal_code`, `town`, `vat_number`, `tax_id` (Germany: the seller's USt-IdNr or Steuernummer; give `vat_number` of the entity or the `tax_number` of its VAT settings) or `vat_designation` (Switzerland: the seller's UID with the register designation MWST, TVA or IVA)."
          },
          "basis": {
            "type": "string",
            "title": "Basis",
            "description": "The legal basis that makes it mandatory, e.g. `Art. 26 Abs. 2 Bst. a: Ort des Leistungserbringers`."
          },
          "record_id": {
            "type": "string",
            "format": "uuid",
            "title": "Record Id",
            "description": "Id of the record to complete: the entity (`seller`) or the customer (`buyer`)."
          }
        },
        "type": "object",
        "required": [
          "party",
          "field",
          "basis",
          "record_id"
        ],
        "title": "ContentGap",
        "description": "One piece of legally required content an invoice lacks, and where it is entered."
      },
      "ContractCancelInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why it is cancelled."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "ContractCancelInput",
        "examples": [
          {
            "reason": "The customer signed a different offer"
          }
        ]
      },
      "ContractChangeAmounts": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "end",
              "modify"
            ],
            "title": "Kind",
            "description": "`end` or `modify`."
          },
          "old_price": {
            "type": "string",
            "title": "Old Price",
            "description": "The transaction price before."
          },
          "new_price": {
            "type": "string",
            "title": "New Price",
            "description": "The transaction price after."
          },
          "old_end_date": {
            "type": "string",
            "format": "date",
            "title": "Old End Date",
            "description": "The last day before."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "The last day after."
          },
          "effective_date": {
            "type": "string",
            "format": "date",
            "title": "Effective Date",
            "description": "The first day the new terms apply to: the day after the last day for an early end, the day asked (default today) for a modification. Revenue the old terms earned before it stays."
          },
          "earned": {
            "type": "string",
            "title": "Earned",
            "description": "`end`: what the schedule earned through the last day (a part of a month by its days), spread over the months not recognised yet; what the price adds beyond it is recognised on the last day. `modify`: the new price, of which what the old terms earned before `effective_date` stays and the rest is spread from it."
          },
          "recognised": {
            "type": "string",
            "title": "Recognised",
            "description": "Revenue recognised so far; it stays."
          },
          "billed": {
            "type": "string",
            "title": "Billed",
            "description": "What the contract billed, net, before the change."
          },
          "credit_total": {
            "type": "string",
            "title": "Credit Total",
            "description": "What the credit notes credit, net of VAT: what was billed beyond the new price. Zero when the price is not below what was billed."
          },
          "to_bill": {
            "type": "string",
            "title": "To Bill",
            "description": "What is left to invoice after the change (new price less what stays billed); revenue recognised before it is billed is a contract asset."
          },
          "credits": {
            "items": {
              "$ref": "#/components/schemas/ContractChangeCredit"
            },
            "type": "array",
            "title": "Credits",
            "description": "A credit note per invoice, dated the day the change is applied."
          },
          "recurring_invoices": {
            "items": {
              "$ref": "#/components/schemas/ContractChangeRecurring"
            },
            "type": "array",
            "title": "Recurring Invoices",
            "description": "The recurring invoices that bill the contract past its new last day: they stop on it when the change is applied."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "old_price",
          "new_price",
          "old_end_date",
          "end_date",
          "effective_date",
          "earned",
          "recognised",
          "billed",
          "credit_total",
          "to_bill",
          "credits",
          "recurring_invoices"
        ],
        "title": "ContractChangeAmounts"
      },
      "ContractChangeAskedOut": {
        "properties": {
          "change": {
            "$ref": "#/components/schemas/ContractChangeOut",
            "description": "The change asked, waiting for approval."
          },
          "approval_id": {
            "type": "string",
            "format": "uuid",
            "title": "Approval Id",
            "description": "The approval request a second person decides (`POST /v1/approvals/{approval_id}/approve`); never the person who asked."
          }
        },
        "type": "object",
        "required": [
          "change",
          "approval_id"
        ],
        "title": "ContractChangeAskedOut"
      },
      "ContractChangeCredit": {
        "properties": {
          "invoice_id": {
            "type": "string",
            "format": "uuid",
            "title": "Invoice Id",
            "description": "The invoice the credit note credits."
          },
          "invoice_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Number",
            "description": "Its number."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What it credits, net of VAT, in the contract's currency."
          }
        },
        "type": "object",
        "required": [
          "invoice_id",
          "invoice_number",
          "amount"
        ],
        "title": "ContractChangeCredit"
      },
      "ContractChangeInput": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "end",
              "modify"
            ],
            "title": "Kind",
            "description": "`end`: end the contract early, on `end_date`, before its last day. `modify`: a new transaction price and/or last day (earlier or later) from `effective_date` (IFRS 15.21(a)); what the old terms earned before that day stays."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "`end`: the last day of service (required). `modify`: the new last day; default the current one."
          },
          "price": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price",
            "description": "The transaction price after the change, net of VAT, in the contract's currency. `end`: default what the schedule earned through `end_date` (a part of a month by its days); a higher price (a fee for ending early) is recognised on the last day. `modify`: default the current price."
          },
          "effective_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Effective Date",
            "description": "`modify` only: the day the change takes effect, the day the parties agreed it; default today where the company is (or the first day of the term, when it starts later). Never before the first day whose revenue is not recognised, and on or before the last day. What the schedule earned before it stays, recognised or not (a part of a month by its days); the rest of the new price is spread from it."
          },
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why the contract changes."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "reason"
        ],
        "title": "ContractChangeInput",
        "examples": [
          {
            "end_date": "2026-04-30",
            "kind": "end",
            "reason": "The customer gave up the maintenance after four months"
          },
          {
            "effective_date": "2026-10-12",
            "end_date": "2027-03-31",
            "kind": "modify",
            "price": "15000.00",
            "reason": "Maintenance extended by three months"
          }
        ]
      },
      "ContractChangeOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the change."
          },
          "contract_id": {
            "type": "string",
            "format": "uuid",
            "title": "Contract Id",
            "description": "The revenue contract."
          },
          "kind": {
            "type": "string",
            "enum": [
              "end",
              "modify"
            ],
            "title": "Kind",
            "description": "`end`: ended early; `modify`: a new price and/or last day."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "The contract's last day after the change."
          },
          "new_price": {
            "type": "string",
            "title": "New Price",
            "description": "The transaction price after the change."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why it was asked."
          },
          "amounts": {
            "$ref": "#/components/schemas/ContractChangeAmounts",
            "description": "What the request named."
          },
          "status": {
            "type": "string",
            "enum": [
              "applied",
              "pending_approval",
              "rejected"
            ],
            "title": "Status",
            "description": "`pending_approval`, `applied` (in force) or `rejected`."
          },
          "modification_plan_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Modification Plan Version",
            "description": "The contract's plan version the change made, once applied."
          },
          "credit_notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Credit Notes",
            "description": "The numbers of the credit notes it made."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved it."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When it was approved, else empty."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who asked."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was asked."
          }
        },
        "type": "object",
        "required": [
          "id",
          "contract_id",
          "kind",
          "end_date",
          "new_price",
          "reason",
          "amounts",
          "status",
          "modification_plan_version",
          "credit_notes",
          "approved_by",
          "approved_at",
          "created_by",
          "created_at"
        ],
        "title": "ContractChangeOut"
      },
      "ContractChangeRecurring": {
        "properties": {
          "template_id": {
            "type": "string",
            "format": "uuid",
            "title": "Template Id",
            "description": "The recurring invoice that bills the contract."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "Its last day after the change: the contract's."
          },
          "ends": {
            "type": "boolean",
            "title": "Ends",
            "description": "True when nothing is left for it to invoice by then: it ends. False: it keeps running to its new last day."
          }
        },
        "type": "object",
        "required": [
          "template_id",
          "name",
          "end_date",
          "ends"
        ],
        "title": "ContractChangeRecurring"
      },
      "ContractModificationOut": {
        "properties": {
          "plan_version": {
            "type": "integer",
            "title": "Plan Version",
            "description": "The plan version it started."
          },
          "effective_date": {
            "type": "string",
            "format": "date",
            "title": "Effective Date",
            "description": "The first day the new terms apply to."
          },
          "old_price": {
            "type": "string",
            "title": "Old Price",
            "description": "The transaction price before."
          },
          "new_price": {
            "type": "string",
            "title": "New Price",
            "description": "The transaction price after."
          },
          "old_end_date": {
            "type": "string",
            "format": "date",
            "title": "Old End Date",
            "description": "The last day before."
          },
          "new_end_date": {
            "type": "string",
            "format": "date",
            "title": "New End Date",
            "description": "The last day after."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why the terms changed, in English."
          },
          "reason_words": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Reason"
              },
              {
                "type": "null"
              }
            ],
            "description": "The same by code (`revenueContracts.change`), for the screens to word in the person's language: a subscription's early end names the subscription, its last day and the reason the person gave; null for a change worded only in `reason`."
          },
          "approved_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Approved By",
            "description": "Who approved the change."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "plan_version",
          "effective_date",
          "old_price",
          "new_price",
          "old_end_date",
          "new_end_date",
          "reason",
          "approved_by",
          "created_at"
        ],
        "title": "ContractModificationOut"
      },
      "ContrastOut": {
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "accent",
              "colour"
            ],
            "title": "Name",
            "description": "Which colour is checked."
          },
          "colour": {
            "type": "string",
            "title": "Colour",
            "description": "The colour checked, `#rrggbb` (the default when none is set)."
          },
          "ratio": {
            "type": "number",
            "title": "Ratio",
            "description": "Its contrast ratio against white (WCAG 2.2), 1 to 21."
          },
          "minimum": {
            "type": "number",
            "title": "Minimum",
            "description": "What it must reach: 4.5 for the brand colour (text on white, white on it), 3 for the accent (rules and bands)."
          },
          "passes": {
            "type": "boolean",
            "title": "Passes",
            "description": "Whether it reaches the minimum."
          }
        },
        "type": "object",
        "required": [
          "name",
          "colour",
          "ratio",
          "minimum",
          "passes"
        ],
        "title": "ContrastOut"
      },
      "ControlsIn": {
        "properties": {
          "controls": {
            "type": "string",
            "title": "Controls",
            "description": "The controls mode: 'ai_reviewer' or 'four_eyes'."
          }
        },
        "type": "object",
        "required": [
          "controls"
        ],
        "title": "ControlsIn",
        "examples": [
          {
            "controls": "four_eyes"
          }
        ]
      },
      "ControlsOut": {
        "properties": {
          "controls": {
            "type": "string",
            "title": "Controls",
            "description": "The controls mode: 'ai_reviewer' or 'four_eyes'."
          }
        },
        "type": "object",
        "required": [
          "controls"
        ],
        "title": "ControlsOut"
      },
      "CopyOut": {
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "Id (uuid) of the test organization; choose it when signing in."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was made (ISO 8601, UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it, as an actor object (`type`, `id`, `name`)."
          },
          "masked": {
            "type": "boolean",
            "title": "Masked",
            "description": "Its business partners are mock values (see `masked`)."
          },
          "cloned_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cloned At",
            "description": "When it was last filled from this organization, made or refreshed (ISO 8601, UTC)."
          },
          "refresh_schedule": {
            "type": "string",
            "enum": [
              "nightly",
              "off",
              "weekly"
            ],
            "title": "Refresh Schedule",
            "description": "When it is refreshed by itself (see `PUT /v1/test-copies/{copy_id}/schedule`): `off`, `nightly` or `weekly`.",
            "default": "off"
          },
          "refresh_problem": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "refresh_failed",
                  "scheduler_not_admin",
                  "source_gone",
                  "source_not_active"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Refresh Problem",
            "description": "Why it was last not refreshed on its schedule; null once it is refreshed again. `refresh_failed`: this organization could not be copied (refresh it by hand to see why); `scheduler_not_admin`: whoever set the schedule is no longer an administrator here (set it again); `source_not_active` or `source_gone`: this organization is not active."
          },
          "refresh_problem_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Refresh Problem At",
            "description": "When it was last not refreshed (ISO 8601, UTC)."
          },
          "remove_requested_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remove Requested At",
            "description": "When its removal was asked for (ISO 8601, UTC); null until then. It leaves this list once it is removed."
          }
        },
        "type": "object",
        "required": [
          "org_id",
          "name",
          "created_at",
          "created_by",
          "masked"
        ],
        "title": "CopyOut",
        "description": "A test organization made from this one."
      },
      "CopyRequest": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The name of the test organization, up to 200 characters. Default: the organization's name followed by `(test)`."
          },
          "masked": {
            "type": "boolean",
            "title": "Masked",
            "description": "Mask the business partners: the names, e-mails, streets, IBANs and contacts of customers, vendors and prospects become mock values everywhere in the copy, and its stored files placeholders. Amounts, setup and the books stay the same.",
            "default": false
          }
        },
        "type": "object",
        "title": "CopyRequest",
        "examples": [
          {
            "masked": true,
            "name": "Muster AG (UAT)"
          }
        ]
      },
      "CountLineInput": {
        "properties": {
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code (or id) of an item on the count."
          },
          "counted_quantity": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counted Quantity",
            "description": "What was counted; null: not counted (yet). A quantity in the item's unit, up to six decimals, e.g. `12` or `2.5`."
          }
        },
        "type": "object",
        "required": [
          "item",
          "counted_quantity"
        ],
        "title": "CountLineInput"
      },
      "CountLinesInput": {
        "properties": {
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CountLineInput"
            },
            "type": "array",
            "maxItems": 2000,
            "minItems": 1,
            "title": "Lines",
            "description": "Counted quantities."
          }
        },
        "type": "object",
        "required": [
          "lines"
        ],
        "title": "CountLinesInput",
        "examples": [
          {
            "lines": [
              {
                "counted_quantity": "37",
                "item": "SCANNER"
              }
            ]
          }
        ]
      },
      "CountryOption": {
        "properties": {
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The country's name in English."
          },
          "region": {
            "type": "string",
            "enum": [
              "ca",
              "ch",
              "eu",
              "no",
              "uk",
              "us"
            ],
            "title": "Region",
            "description": "`eu`, `no` (Norway), `uk`, `ch` (Switzerland and Liechtenstein), `us` or `ca`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The country's currency, the default of the books."
          },
          "currencies": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Currencies",
            "description": "The currencies the books may be kept in."
          },
          "standards": {
            "items": {
              "$ref": "#/components/schemas/FrameworkOption"
            },
            "type": "array",
            "title": "Standards",
            "description": "The accounting standards a company there may report under, the default first."
          },
          "tax": {
            "type": "string",
            "enum": [
              "gst_hst",
              "sales_tax",
              "vat"
            ],
            "title": "Tax",
            "description": "The indirect tax: `vat`, `sales_tax` (US, per state) or `gst_hst` (Canada)."
          },
          "tax_periods": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Tax Periods",
            "description": "The return periods allowed, the default first (`month`, `two_months`, `quarter`, `half_year`, `year`); empty when none is asked."
          },
          "tax_number_label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Number Label",
            "description": "What the tax registration number is called; null when none is asked."
          },
          "vat_return_form": {
            "type": "boolean",
            "title": "Vat Return Form",
            "description": "Whether the VAT return is prepared on the official form; false: VAT is booked and reported per rate, and the return is filed outside the books for now."
          },
          "subdivisions": {
            "items": {
              "$ref": "#/components/schemas/Subdivision"
            },
            "type": "array",
            "title": "Subdivisions",
            "description": "The states or provinces, one of which must be chosen; empty when none is."
          }
        },
        "type": "object",
        "required": [
          "country",
          "name",
          "region",
          "currency",
          "currencies",
          "standards",
          "tax",
          "tax_periods",
          "tax_number_label",
          "vat_return_form",
          "subdivisions"
        ],
        "title": "CountryOption"
      },
      "CreditExposure": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "Today where the company is: amounts in another currency are converted at this day's ECB reference rate."
          },
          "customers": {
            "items": {
              "$ref": "#/components/schemas/CreditPosition"
            },
            "type": "array",
            "title": "Customers",
            "description": "Every customer with a credit limit, those over it first, then by code."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "as_of",
          "customers"
        ],
        "title": "CreditExposure",
        "description": "The customers of a company with a credit limit, and their exposure today."
      },
      "CreditPosition": {
        "properties": {
          "party": {
            "type": "string",
            "title": "Party",
            "description": "The customer's code, e.g. `C-SE`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The customer's name."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The customer's currency: every amount here is in it."
          },
          "credit_limit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Limit",
            "description": "The most the customer may owe; null for no limit."
          },
          "receivables": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receivables",
            "description": "What the customer owes on posted documents: open invoices less open credit notes and payments received on account."
          },
          "pending_invoices": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pending Invoices",
            "description": "The totals of its invoices waiting for a second person's approval."
          },
          "open_orders": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Open Orders",
            "description": "What is left to invoice on its open sales orders, VAT included."
          },
          "exposure": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exposure",
            "description": "receivables + pending_invoices + open_orders; null when an amount in another currency has no exchange rate today (`note`)."
          },
          "available": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Available",
            "description": "credit_limit - exposure: what may still be invoiced or ordered; negative when over the limit; null without a limit."
          },
          "over_limit": {
            "type": "boolean",
            "title": "Over Limit",
            "description": "`true` when the exposure is above the credit limit."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why the exposure could not be worked out (an exchange rate missing today)."
          }
        },
        "type": "object",
        "required": [
          "party",
          "name",
          "currency",
          "credit_limit",
          "receivables",
          "pending_invoices",
          "open_orders",
          "exposure",
          "available",
          "over_limit"
        ],
        "title": "CreditPosition",
        "description": "One customer's credit exposure against its credit limit, in the customer's currency."
      },
      "CsvMapping": {
        "properties": {
          "date": {
            "type": "string",
            "title": "Date",
            "description": "The booking date column.",
            "default": "date"
          },
          "amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "The signed amount column (negative is money out); not used when `credit` or `debit` is named.",
            "default": "amount"
          },
          "credit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit",
            "description": "A column of money in, for files with separate columns."
          },
          "debit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Debit",
            "description": "A column of money out, for files with separate columns: the line's amount is credit less debit, whatever the sign the file writes them with."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "A currency column; without one, `default_currency` applies."
          },
          "counterparty": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty",
            "description": "The column naming who paid or was paid.",
            "default": "counterparty"
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "The column of the counterparty's IBAN."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The column of the payment reference.",
            "default": "reference"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "The column of the booking text.",
            "default": "description"
          },
          "bank_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Reference",
            "description": "A column of the bank's unique transaction id: a later file that overlaps skips the lines it holds by it."
          },
          "date_format": {
            "type": "string",
            "title": "Date Format",
            "description": "How the dates are written, as a strptime pattern, e.g. `%d.%m.%Y`.",
            "default": "%Y-%m-%d"
          },
          "decimal_comma": {
            "type": "boolean",
            "title": "Decimal Comma",
            "description": "True when amounts are written 1.234,50 instead of 1,234.50.",
            "default": false
          },
          "delimiter": {
            "type": "string",
            "maxLength": 1,
            "minLength": 1,
            "title": "Delimiter",
            "description": "The column separator: `,` `;` or a tab.",
            "default": ","
          },
          "default_currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Currency",
            "description": "For files without a currency column; default: the bank account's currency."
          }
        },
        "type": "object",
        "title": "CsvMapping",
        "description": "Column names in the file; amounts may use a decimal comma."
      },
      "CsvPreview": {
        "properties": {
          "columns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Columns",
            "description": "The column names in the file's first line."
          },
          "mapping": {
            "$ref": "#/components/schemas/CsvMapping",
            "description": "The mapping the file was read with: the one sent, or the guess from the file's header names and values when none was sent. Send it with the import."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Code of the bank account the lines would be booked on."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "Name of that account."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The account's currency."
          },
          "statement_ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Statement Ref",
            "description": "The name the statement would get, e.g. `CSV 1020 01.09.2026-30.09.2026`; null when the file cannot be read."
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Number of transactions read (lines with an amount of 0 are left out)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ParsedLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The first 200 transactions read."
          },
          "from_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Date",
            "description": "The earliest booking date."
          },
          "to_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "To Date",
            "description": "The latest booking date."
          },
          "money_in": {
            "type": "string",
            "title": "Money In",
            "description": "Sum of the credits."
          },
          "money_out": {
            "type": "string",
            "title": "Money Out",
            "description": "Sum of the debits, as a positive amount."
          },
          "duplicates": {
            "type": "integer",
            "title": "Duplicates",
            "description": "Transactions the account already holds; the import skips them."
          },
          "problem": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BlockerOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "Why the file cannot be read with this mapping, as the import would refuse it (`csv_column_missing` with `column`, `csv_line_unreadable` with `line`, `csv_line_no_currency`, `csv_no_transactions`, `statement_currency_differs`, `statement_imported`); null when it can be imported."
          }
        },
        "type": "object",
        "required": [
          "columns",
          "mapping",
          "account",
          "account_name",
          "currency",
          "statement_ref",
          "count",
          "lines",
          "from_date",
          "to_date",
          "money_in",
          "money_out",
          "duplicates",
          "problem"
        ],
        "title": "CsvPreview",
        "description": "What importing a CSV file would do, read with ``mapping``; nothing is stored."
      },
      "CtaRollForward": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the run."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The reporting currency."
          },
          "entities": {
            "items": {
              "$ref": "#/components/schemas/EntityRollForward"
            },
            "type": "array",
            "title": "Entities",
            "description": "One roll-forward per translated subsidiary (an entity in the reporting currency has none)."
          },
          "closing_reserve": {
            "type": "string",
            "title": "Closing Reserve",
            "description": "The group's translation reserve: the sum over the entities."
          },
          "reconciled": {
            "type": "boolean",
            "title": "Reconciled",
            "description": "True when every entity reconciles."
          }
        },
        "type": "object",
        "required": [
          "run",
          "currency",
          "entities",
          "closing_reserve",
          "reconciled"
        ],
        "title": "CtaRollForward"
      },
      "CurrencyAmount": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The amount in that currency."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "amount"
        ],
        "title": "CurrencyAmount"
      },
      "CurrencyRow": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Document currency."
          },
          "a_receivable": {
            "type": "string",
            "title": "A Receivable",
            "description": "`entity_a`'s receivable from `entity_b`: its open sales invoices to it, less its open credit notes."
          },
          "a_payable": {
            "type": "string",
            "title": "A Payable",
            "description": "`entity_a`'s payable to `entity_b`: its open bills."
          },
          "b_receivable": {
            "type": "string",
            "title": "B Receivable",
            "description": "`entity_b`'s receivable from `entity_a`."
          },
          "b_payable": {
            "type": "string",
            "title": "B Payable",
            "description": "`entity_b`'s payable to `entity_a`."
          },
          "a_net": {
            "type": "string",
            "title": "A Net",
            "description": "`a_receivable` less `a_payable`."
          },
          "b_net": {
            "type": "string",
            "title": "B Net",
            "description": "`b_receivable` less `b_payable`."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`a_net` plus `b_net`: zero when both sides agree exactly."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "a_receivable",
          "a_payable",
          "b_receivable",
          "b_payable",
          "a_net",
          "b_net",
          "difference"
        ],
        "title": "CurrencyRow",
        "description": "The open items of a pair in one document currency, in the document currency: neither\nfunctional currency, so a revaluation cannot disturb the comparison."
      },
      "CurrencyTotal": {
        "properties": {
          "bills": {
            "type": "integer",
            "title": "Bills",
            "description": "Number of bills."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount to pay in total, after discounts."
          },
          "discount": {
            "type": "string",
            "title": "Discount",
            "description": "Cash discounts taken in total."
          }
        },
        "type": "object",
        "required": [
          "bills",
          "amount",
          "discount"
        ],
        "title": "CurrencyTotal"
      },
      "CustomFieldInput": {
        "properties": {
          "record": {
            "type": "string",
            "enum": [
              "company",
              "contact",
              "deal"
            ],
            "title": "Record",
            "description": "`company`, `contact` or `deal`."
          },
          "key": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]{0,39}$",
            "title": "Key",
            "description": "How the API names it: lower case letters, digits and `_`, e.g. `industry`; never changes."
          },
          "label": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Label",
            "description": "What the screens call it."
          },
          "type": {
            "type": "string",
            "enum": [
              "choice",
              "date",
              "number",
              "text",
              "yes_no"
            ],
            "title": "Type",
            "description": "`text`, `number`, `date`, `yes_no` or `choice`; never changes."
          },
          "choices": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Choices",
            "description": "For `choice`: the choices, in order (1 to 50)."
          },
          "position": {
            "type": "integer",
            "maximum": 1000.0,
            "minimum": 0.0,
            "title": "Position",
            "description": "Lower comes first.",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "record",
          "key",
          "label",
          "type"
        ],
        "title": "CustomFieldInput",
        "examples": [
          {
            "choices": [
              "Retail",
              "Manufacturing",
              "Services"
            ],
            "key": "industry",
            "label": "Industry",
            "record": "company",
            "type": "choice"
          },
          {
            "key": "competitor",
            "label": "Competitor",
            "record": "deal",
            "type": "text"
          }
        ]
      },
      "CustomFieldOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the field."
          },
          "record": {
            "type": "string",
            "enum": [
              "company",
              "contact",
              "deal"
            ],
            "title": "Record",
            "description": "`company`, `contact` or `deal`."
          },
          "key": {
            "type": "string",
            "title": "Key",
            "description": "How the API names it."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "What the screens call it."
          },
          "type": {
            "type": "string",
            "enum": [
              "choice",
              "date",
              "number",
              "text",
              "yes_no"
            ],
            "title": "Type",
            "description": "`text`, `number`, `date`, `yes_no` or `choice`."
          },
          "choices": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Choices",
            "description": "A choice field's choices."
          },
          "position": {
            "type": "integer",
            "title": "Position",
            "description": "Lower comes first."
          },
          "retired": {
            "type": "boolean",
            "title": "Retired",
            "description": "Hidden from forms; its values stay readable."
          }
        },
        "type": "object",
        "required": [
          "id",
          "record",
          "key",
          "label",
          "type",
          "position",
          "retired"
        ],
        "title": "CustomFieldOut"
      },
      "CustomFieldUpdate": {
        "properties": {
          "label": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Label",
            "description": "New label."
          },
          "choices": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Choices",
            "description": "A choice field's new choices; a choice a record holds stays in the list."
          },
          "position": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 1000.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Position",
            "description": "New position."
          },
          "retired": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Retired",
            "description": "`true` hides the field from forms (its values stay readable); `false` brings it back."
          }
        },
        "type": "object",
        "title": "CustomFieldUpdate",
        "examples": [
          {
            "label": "Sector"
          },
          {
            "retired": true
          }
        ]
      },
      "CustomerActivity": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "The first day of the period."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "The last day of the period."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of its PDF: the customer's, else the one spoken in its country."
          },
          "currencies": {
            "items": {
              "$ref": "#/components/schemas/CustomerActivityCurrency"
            },
            "type": "array",
            "title": "Currencies",
            "description": "One block per currency the customer has movements or a balance in, by code: the currency of each invoice, credit note and payment."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The entity's functional currency."
          },
          "closing_functional": {
            "type": "string",
            "title": "Closing Functional",
            "description": "What the customer owes at the end of `end` in the functional currency: its lines on the receivables control account, revaluations included (the `control_balance` of the open-items statement of that day)."
          },
          "open_items": {
            "items": {
              "$ref": "#/components/schemas/StatementItem"
            },
            "type": "array",
            "title": "Open Items",
            "description": "The invoices, credit notes and amounts on account still open at the end of `end`, oldest due date first (credit notes negative): the open-items statement of that day."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "party_id",
          "party_code",
          "party",
          "start",
          "end",
          "language",
          "currencies",
          "functional_currency",
          "closing_functional",
          "open_items"
        ],
        "title": "CustomerActivity",
        "description": "A customer's activity statement: what the customer owes us, by invoice, credit note and\npayment, between two days."
      },
      "CustomerActivityCurrency": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the amounts."
          },
          "opening": {
            "type": "string",
            "title": "Opening",
            "description": "What the customer owed at the start of the first day."
          },
          "increases": {
            "type": "string",
            "title": "Increases",
            "description": "The sum of the positive movements."
          },
          "decreases": {
            "type": "string",
            "title": "Decreases",
            "description": "The sum of the negative movements (a negative amount)."
          },
          "closing": {
            "type": "string",
            "title": "Closing",
            "description": "What the customer owed at the end of the last day: `opening + increases + decreases`. A negative amount is a credit of the customer."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/CustomerActivityLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The movements, oldest first."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "opening",
          "increases",
          "decreases",
          "closing",
          "lines"
        ],
        "title": "CustomerActivityCurrency",
        "description": "The movements of one currency, from the opening to the closing balance."
      },
      "CustomerActivityLine": {
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The day it was booked."
          },
          "kind": {
            "type": "string",
            "enum": [
              "application",
              "credit_note",
              "invoice",
              "other",
              "payment",
              "payment_reversal",
              "write_off"
            ],
            "title": "Kind",
            "description": "`invoice`, `credit_note`, `payment` (a payment received, or a refund paid out), `payment_reversal`, `application` (an amount on account or a credit note applied to an invoice later, ADR-0045: one line off the payment or credit note, one on the invoice), or `other` (an opening balance or a manual entry)."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "Our number: the invoice's, the credit note's, the payment's or the entry's."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The invoice or credit note it concerns."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "The number of that invoice or credit note (for a payment: the one it pays)."
          },
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "The journal entry that booked it."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "In the currency of the block: positive when it raises what the customer owes (an invoice), negative when it lowers it (a payment, a credit note)."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "What the customer owes after it: the running balance."
          }
        },
        "type": "object",
        "required": [
          "day",
          "kind",
          "reference",
          "document_id",
          "document_number",
          "entry_id",
          "amount",
          "balance"
        ],
        "title": "CustomerActivityLine",
        "description": "One movement on the customer's account: an invoice, a credit note, a payment received."
      },
      "CustomerContext": {
        "properties": {
          "open_invoices": {
            "type": "integer",
            "title": "Open Invoices",
            "description": "Number of open posted documents for this customer.",
            "default": 0
          },
          "overdue_invoices": {
            "type": "integer",
            "title": "Overdue Invoices",
            "description": "Number of overdue posted documents for this customer.",
            "default": 0
          },
          "active_subscriptions": {
            "type": "integer",
            "title": "Active Subscriptions",
            "description": "Number of active recurring subscriptions for this customer.",
            "default": 0
          },
          "open_opportunities": {
            "type": "integer",
            "title": "Open Opportunities",
            "description": "Number of open sales pipeline deals for this customer.",
            "default": 0
          }
        },
        "type": "object",
        "title": "CustomerContext",
        "description": "Cross-function customer summary shown on a support case."
      },
      "CustomerDefined": {
        "properties": {
          "kind": {
            "type": "string",
            "const": "chart_of_accounts",
            "title": "Kind",
            "description": "`chart_of_accounts`: the configuration is the entity's chart of accounts."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "entity_name": {
            "type": "string",
            "title": "Entity Name",
            "description": "Name of the entity."
          },
          "active": {
            "type": "integer",
            "title": "Active",
            "description": "Active accounts."
          },
          "template": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Template",
            "description": "Chart template the entity started from, e.g. 'ch_kmu'."
          },
          "last_added_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Added At",
            "description": "Newest account."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "entity",
          "entity_name",
          "active"
        ],
        "title": "CustomerDefined",
        "description": "Configuration the organization defines and maintains itself (not reference data)."
      },
      "CustomerMerge": {
        "properties": {
          "into": {
            "type": "string",
            "minLength": 1,
            "title": "Into",
            "description": "Code or id of the customer that stays (same company)."
          }
        },
        "type": "object",
        "required": [
          "into"
        ],
        "title": "CustomerMerge",
        "examples": [
          {
            "into": "C-CH"
          }
        ]
      },
      "CustomerPrice": {
        "properties": {
          "price_list_id": {
            "type": "string",
            "format": "uuid",
            "title": "Price List Id",
            "description": "The customer's price list."
          },
          "price_list": {
            "type": "string",
            "title": "Price List",
            "description": "Its code."
          },
          "price_list_name": {
            "type": "string",
            "title": "Price List Name",
            "description": "Its name."
          },
          "price_id": {
            "type": "string",
            "format": "uuid",
            "title": "Price Id",
            "description": "The price on the list."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net price of one unit for the customer."
          },
          "price_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Period",
            "description": "Per `month` or `year`, or per unit."
          },
          "min_quantity": {
            "type": "string",
            "title": "Min Quantity",
            "description": "The tier it came from: its smallest quantity."
          },
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day it applies."
          }
        },
        "type": "object",
        "required": [
          "price_list_id",
          "price_list",
          "price_list_name",
          "price_id",
          "currency",
          "unit_price",
          "price_period",
          "min_quantity",
          "valid_from"
        ],
        "title": "CustomerPrice"
      },
      "CustomerPriceListOut": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency the customer takes the list in."
          },
          "price_list_id": {
            "type": "string",
            "format": "uuid",
            "title": "Price List Id",
            "description": "Price list id."
          },
          "price_list": {
            "type": "string",
            "title": "Price List",
            "description": "Price list code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Price list name."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether the list is active (an inactive one is not used)."
          },
          "assigned_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Assigned By",
            "description": "Who gave it to the customer."
          },
          "assigned_at": {
            "type": "string",
            "format": "date-time",
            "title": "Assigned At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "price_list_id",
          "price_list",
          "name",
          "active",
          "assigned_by",
          "assigned_at"
        ],
        "title": "CustomerPriceListOut",
        "examples": [
          {
            "active": true,
            "assigned_at": "2026-01-01T08:00:00Z",
            "assigned_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "name": "Wholesale CHF",
            "price_list": "WHOLESALE-CHF",
            "price_list_id": "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b"
          }
        ]
      },
      "CustomerPriceListSet": {
        "properties": {
          "price_list": {
            "type": "string",
            "title": "Price List",
            "description": "Code (or id) of an active price list of the customer's entity in the currency of the path."
          }
        },
        "type": "object",
        "required": [
          "price_list"
        ],
        "title": "CustomerPriceListSet",
        "examples": [
          {
            "price_list": "WHOLESALE-CHF"
          }
        ]
      },
      "DataImportResult": {
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "accounts",
              "customers",
              "open_payables",
              "open_receivables",
              "opening_balances",
              "vendors"
            ],
            "title": "Type",
            "description": "The kind of import."
          },
          "mode": {
            "type": "string",
            "enum": [
              "commit",
              "dry_run"
            ],
            "title": "Mode",
            "description": "`dry_run` (nothing is saved) or `commit` (all or nothing)."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity the import is for."
          },
          "format": {
            "type": "string",
            "enum": [
              "csv",
              "xlsx"
            ],
            "title": "Format",
            "description": "`csv` or `xlsx`, as detected from the file."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "The uploaded file's name."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the file, kept in the audit trail."
          },
          "as_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "As Of",
            "description": "The opening date of an `opening_balances` or open item import; null otherwise."
          },
          "rows": {
            "type": "integer",
            "title": "Rows",
            "description": "Data rows in the file (empty rows are skipped)."
          },
          "ok": {
            "type": "boolean",
            "title": "Ok",
            "description": "True when the file has no error: a dry run says a commit would succeed; a commit has succeeded."
          },
          "committed": {
            "type": "boolean",
            "title": "Committed",
            "description": "True only for a commit that changed the books; always false for a dry run."
          },
          "errors": {
            "items": {
              "$ref": "#/components/schemas/ImportIssue"
            },
            "type": "array",
            "title": "Errors",
            "description": "Every row-level problem found (all of them, not the first): a dry run lists them with 200, a commit refuses with 422 and the same list."
          },
          "warnings": {
            "items": {
              "$ref": "#/components/schemas/ImportIssue"
            },
            "type": "array",
            "title": "Warnings",
            "description": "Things worth knowing that do not stop the import, e.g. an ignored column or a trial balance row for a control account."
          },
          "summary": {
            "$ref": "#/components/schemas/ImportSummary",
            "description": "What was (or would be) created."
          },
          "rates_to_confirm": {
            "type": "integer",
            "title": "Rates To Confirm",
            "description": "Rows whose `fx_rate` differs by more than 10% from the reference rate of the opening date: problems unless the import was sent with `confirm_rates`, warnings with it.",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "type",
          "mode",
          "entity",
          "format",
          "filename",
          "sha256",
          "as_of",
          "rows",
          "ok",
          "committed",
          "errors",
          "warnings",
          "summary"
        ],
        "title": "DataImportResult"
      },
      "DataSource": {
        "properties": {
          "authority": {
            "type": "string",
            "title": "Authority",
            "description": "Id of the authority in the source register."
          },
          "authority_name": {
            "type": "string",
            "title": "Authority Name",
            "description": "Name of the authority."
          },
          "homepage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Homepage",
            "description": "The authority's home page; null if none."
          },
          "hosts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Hosts",
            "description": "Host names the authority publishes the data on."
          },
          "licence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Licence",
            "description": "Licence the data is published under; null if not stated."
          },
          "domain": {
            "type": "string",
            "title": "Domain",
            "description": "The kind of reference data, as in the register."
          },
          "domain_title": {
            "type": "string",
            "title": "Domain Title",
            "description": "Its name in words."
          },
          "jurisdictions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Jurisdictions",
            "description": "The jurisdictions the data point covers."
          },
          "method": {
            "type": "string",
            "title": "Method",
            "description": "How the register says the data is obtained."
          },
          "cadence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cadence",
            "description": "How often the data changes; null if not stated."
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "Where the data is published; null if not stated."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Remarks from the register; null if none."
          },
          "used_by": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Used By",
            "description": "Where the ERP uses this domain (the register)."
          },
          "feeds": {
            "items": {
              "$ref": "#/components/schemas/FeedOut"
            },
            "type": "array",
            "title": "Feeds",
            "description": "The automatic feeds that keep the data current."
          },
          "records": {
            "items": {
              "$ref": "#/components/schemas/RecordsOut"
            },
            "type": "array",
            "title": "Records",
            "description": "How many records the data point holds, per dataset."
          },
          "records_total": {
            "type": "integer",
            "title": "Records Total",
            "description": "Total number of records over all datasets.",
            "default": 0
          },
          "state": {
            "type": "string",
            "enum": [
              "error",
              "no_data",
              "ok",
              "stale",
              "unknown"
            ],
            "title": "State",
            "description": "`ok`, `stale` (older than its freshness rule allows), `no_data`, `error` or `unknown`."
          },
          "detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Detail",
            "description": "A sentence explaining the state; null if none."
          },
          "latest_data": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Latest Data",
            "description": "Newest stored date of the ingest feeds."
          },
          "last_run": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IngestRunOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The most recent ingest run of its feeds."
          },
          "oldest_verified_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Oldest Verified At",
            "description": "The oldest date a maintainer last checked a record against its source (ISO 8601); null if none."
          },
          "newest_verified_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Newest Verified At",
            "description": "The newest such check date (ISO 8601); null if none."
          },
          "cited_urls": {
            "type": "integer",
            "title": "Cited Urls",
            "description": "Number of source URLs the records cite.",
            "default": 0
          },
          "watched_urls": {
            "type": "integer",
            "title": "Watched Urls",
            "description": "Number of those URLs that are watched for changes.",
            "default": 0
          },
          "unreachable_urls": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unreachable Urls",
            "description": "Cited URLs that could not be reached at the last check."
          }
        },
        "type": "object",
        "required": [
          "authority",
          "authority_name",
          "domain",
          "domain_title",
          "jurisdictions",
          "method",
          "state"
        ],
        "title": "DataSource",
        "description": "One data point of the source register with its status."
      },
      "DataSourcesOut": {
        "properties": {
          "connection": {
            "$ref": "#/components/schemas/Connection",
            "description": "The connection to the reference-data service."
          },
          "as_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "As Of",
            "description": "The date the status refers to (ISO 8601)."
          },
          "summary": {
            "$ref": "#/components/schemas/Summary",
            "description": "Counts of the needed data points by state."
          },
          "needs": {
            "items": {
              "$ref": "#/components/schemas/Need"
            },
            "type": "array",
            "title": "Needs",
            "description": "The data points the organization's entities and features need."
          },
          "other": {
            "items": {
              "$ref": "#/components/schemas/DataSource"
            },
            "type": "array",
            "title": "Other",
            "description": "Registered data points the org does not need."
          },
          "customer_defined": {
            "items": {
              "$ref": "#/components/schemas/CustomerDefined"
            },
            "type": "array",
            "title": "Customer Defined",
            "description": "Defined by the organization: its charts of accounts."
          },
          "watcher": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WatcherOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The legislation watcher's last run; null when there is none."
          },
          "status_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Error",
            "description": "Why freshness is unknown (the register loaded, status not)."
          }
        },
        "type": "object",
        "required": [
          "connection",
          "summary",
          "needs",
          "other"
        ],
        "title": "DataSourcesOut"
      },
      "DayRate": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "The day the rate is for."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "Units of the report currency per one unit of the company's currency."
          },
          "fixing_date": {
            "type": "string",
            "format": "date",
            "title": "Fixing Date",
            "description": "The ECB fixing used: the day itself, or the last one before it (a weekend, a holiday)."
          }
        },
        "type": "object",
        "required": [
          "date",
          "rate",
          "fixing_date"
        ],
        "title": "DayRate"
      },
      "Decision": {
        "properties": {
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "Why you approve or reject; stored with the decision and the audit event. Null when omitted."
          }
        },
        "type": "object",
        "title": "Decision",
        "examples": [
          {
            "comment": "Checked against the vendor statement"
          }
        ]
      },
      "DeleteOrganizationInput": {
        "properties": {
          "confirm_name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Confirm Name",
            "description": "The organization's exact name, as it is written (no trimming, no case folding): a guard against deleting the wrong one."
          },
          "accept_activity": {
            "type": "boolean",
            "title": "Accept Activity",
            "description": "Delete it although it shows signs of real use (the evidence of the organization's detail, `customer_grade`): its books are deleted with it. Without it, such an organization is refused with 409 `customer_activity`.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "confirm_name"
        ],
        "title": "DeleteOrganizationInput",
        "examples": [
          {
            "confirm_name": "Muster Treuhand AG"
          }
        ]
      },
      "DeleteOrganizationResult": {
        "properties": {
          "organization": {
            "$ref": "#/components/schemas/TenantOut",
            "description": "The organization, with `remove_requested_at` set: deleted for good after `delete_after`, and until then the deletion can be undone."
          },
          "changed": {
            "type": "boolean",
            "title": "Changed",
            "description": "False when its deletion was asked for already."
          },
          "evidence": {
            "$ref": "#/components/schemas/OrganizationEvidence",
            "description": "The evidence of use that was measured."
          }
        },
        "type": "object",
        "required": [
          "organization",
          "changed",
          "evidence"
        ],
        "title": "DeleteOrganizationResult"
      },
      "DeliveryAddress": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Name of the recipient at the address (up to 70 characters)."
          },
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street (up to 70 characters)."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number (up to 16 characters)."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code (up to 16 characters)."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town (up to 35 characters)."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code in capitals, e.g. `CH`."
          }
        },
        "type": "object",
        "title": "DeliveryAddress"
      },
      "DeliveryInvoiceInput": {
        "properties": {
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "The invoice's day; default today, not before the delivery."
          }
        },
        "type": "object",
        "title": "DeliveryInvoiceInput",
        "examples": [
          {
            "document_date": "2026-10-12"
          }
        ]
      },
      "DeliveryNoteInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity that ships."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Code (or id) of the customer the goods go to."
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "Code (or id) of the warehouse they leave; default the default."
          },
          "delivery_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Date",
            "description": "The day the goods leave (YYYY-MM-DD), the day cost of goods sold is booked; default today. Not after today when the note is posted."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's reference, e.g. its order number."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Printed on the note."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/DeliveryNoteLineInput"
            },
            "type": "array",
            "maxItems": 500,
            "minItems": 1,
            "title": "Lines",
            "description": "What is shipped, at least one line."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "customer",
          "lines"
        ],
        "title": "DeliveryNoteInput",
        "examples": [
          {
            "customer": "C-ZH",
            "customer_reference": "PO-4711",
            "delivery_date": "2026-10-12",
            "entity": "CH01",
            "lines": [
              {
                "item": "SCANNER",
                "quantity": "4"
              },
              {
                "item": "LABELPRN",
                "quantity": "10"
              }
            ],
            "warehouse": "ZRH"
          }
        ]
      },
      "DeliveryNoteLineInput": {
        "properties": {
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Code (or id) of the stock item shipped (`GET /v1/stock-items`)."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Quantity",
            "description": "Quantity shipped in the item's unit, above 0, up to six decimals."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text printed on the note; default the item's name."
          },
          "sales_line": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Line",
            "description": "Id of the sales order line it delivers (`GET /v1/sales-documents/{document}`): an order of the same customer, of the same product. The notes of an order line never ship more than was ordered less what was closed (`422`)."
          }
        },
        "type": "object",
        "required": [
          "item",
          "quantity"
        ],
        "title": "DeliveryNoteLineInput"
      },
      "DeliveryNoteLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the line: what an invoice line names (`delivery_line`)."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Position, from 1."
          },
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Stock item (product code)."
          },
          "item_name": {
            "type": "string",
            "title": "Item Name",
            "description": "Its name."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "Its unit."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Text printed on the note."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity shipped."
          },
          "sales_line_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Line Id",
            "description": "The sales order line it delivers."
          },
          "sales_order": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Order",
            "description": "The number of that order."
          },
          "cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost",
            "description": "The value the goods left with, in the functional currency: booked as cost of goods sold; null until the note posts."
          },
          "invoiced": {
            "type": "string",
            "title": "Invoiced",
            "description": "Quantity on invoices that count (not void or rejected) less what credit notes took back."
          },
          "returned": {
            "type": "string",
            "title": "Returned",
            "description": "Quantity that came back with credit notes."
          },
          "left": {
            "type": "string",
            "title": "Left",
            "description": "Delivered and not invoiced: quantity less returned less invoiced."
          }
        },
        "type": "object",
        "required": [
          "id",
          "line_no",
          "item",
          "item_name",
          "unit",
          "description",
          "quantity",
          "sales_line_id",
          "sales_order",
          "cost",
          "invoiced",
          "returned",
          "left"
        ],
        "title": "DeliveryNoteLineOut"
      },
      "DeliveryNoteOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Delivery note id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "`DN-2026-000001`, given when posted; null on a draft."
          },
          "status": {
            "type": "string",
            "enum": [
              "cancelled",
              "draft",
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "`draft`, `pending_approval` (its stock posting waits for a person), `posted` or `cancelled`."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Customer name."
          },
          "warehouse": {
            "type": "string",
            "title": "Warehouse",
            "description": "Warehouse code."
          },
          "warehouse_name": {
            "type": "string",
            "title": "Warehouse Name",
            "description": "Warehouse name."
          },
          "delivery_date": {
            "type": "string",
            "format": "date",
            "title": "Delivery Date",
            "description": "The day the goods leave."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's reference."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Printed notes."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The functional currency the cost is in."
          },
          "cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost",
            "description": "Cost of goods sold of the note; null until posted."
          },
          "posting_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Id",
            "description": "Its stock posting (`GET /v1/stock-postings`)."
          },
          "posting_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Number",
            "description": "The stock posting's number."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "The entry of cost of goods sold."
          },
          "invoices": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Invoices",
            "description": "Numbers (or ids, of drafts) of the invoices of it."
          },
          "left": {
            "type": "string",
            "title": "Left",
            "description": "Delivered and not invoiced, all lines together."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/DeliveryNoteLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "Its lines."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "Raised by each change."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "decided_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided By",
            "description": "Who posted or cancelled it."
          },
          "decided_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "status",
          "customer",
          "customer_name",
          "warehouse",
          "warehouse_name",
          "delivery_date",
          "customer_reference",
          "notes",
          "currency",
          "cost",
          "posting_id",
          "posting_number",
          "journal_entry_id",
          "invoices",
          "left",
          "lines",
          "version",
          "created_by",
          "created_at",
          "decided_by",
          "decided_at"
        ],
        "title": "DeliveryNoteOut"
      },
      "DeliveryNoteUpdate": {
        "properties": {
          "customer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer",
            "description": "New customer (code or id)."
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "New warehouse (code or id)."
          },
          "delivery_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Date",
            "description": "New delivery day."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "New customer reference."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "New notes."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/DeliveryNoteLineInput"
                },
                "type": "array",
                "maxItems": 500,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "Replaces every line."
          }
        },
        "type": "object",
        "title": "DeliveryNoteUpdate",
        "examples": [
          {
            "delivery_date": "2026-10-13"
          }
        ]
      },
      "DeliveryOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The delivery's id (`send-again` takes it)."
          },
          "endpoint_id": {
            "type": "string",
            "format": "uuid",
            "title": "Endpoint Id",
            "description": "The endpoint it goes to."
          },
          "event_id": {
            "type": "string",
            "format": "uuid",
            "title": "Event Id",
            "description": "The event's id: `webhook-id` of every attempt."
          },
          "event_type": {
            "type": "string",
            "title": "Event Type",
            "description": "The event, e.g. `invoice.posted`."
          },
          "status": {
            "type": "string",
            "enum": [
              "failed",
              "pending",
              "succeeded"
            ],
            "title": "Status",
            "description": "`pending` (to go out or to try again), `succeeded` (delivered), `failed` (every attempt failed; send it again)."
          },
          "attempts": {
            "type": "integer",
            "title": "Attempts",
            "description": "Attempts made so far."
          },
          "next_attempt_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Attempt At",
            "description": "When it is tried next; null if not."
          },
          "last_attempt_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Attempt At",
            "description": "When it was last tried."
          },
          "response_status": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Response Status",
            "description": "The HTTP status of the last attempt."
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error",
            "description": "Why the last attempt failed."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the event happened."
          },
          "delivered_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivered At",
            "description": "When it was delivered."
          },
          "log": {
            "items": {
              "$ref": "#/components/schemas/AttemptOut"
            },
            "type": "array",
            "title": "Log",
            "description": "The attempts, the latest last (at most 20)."
          },
          "payload": {
            "additionalProperties": true,
            "type": "object",
            "title": "Payload",
            "description": "The message body sent."
          }
        },
        "type": "object",
        "required": [
          "id",
          "endpoint_id",
          "event_id",
          "event_type",
          "status",
          "attempts",
          "next_attempt_at",
          "last_attempt_at",
          "response_status",
          "last_error",
          "created_at",
          "delivered_at",
          "log",
          "payload"
        ],
        "title": "DeliveryOut"
      },
      "DeployOut": {
        "properties": {
          "version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Version",
            "description": "The image tag of the latest revision: the first 12 characters of the commit."
          },
          "latest_revision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Latest Revision",
            "description": "The latest ready revision."
          },
          "serving_revision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Serving Revision",
            "description": "The revision with the largest traffic share. It differs from `latest_revision` during a canary and after a rollback."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When the service last changed: a deploy, a rollback or a settings change (ISO 8601, UTC)."
          }
        },
        "type": "object",
        "required": [
          "version",
          "latest_revision",
          "serving_revision",
          "updated_at"
        ],
        "title": "DeployOut",
        "description": "What the Cloud Run service runs."
      },
      "Destination": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "dividend_payable",
              "group_dividend",
              "legal_profit_reserve",
              "retained_earnings",
              "voluntary_reserve"
            ],
            "title": "Kind",
            "description": "`retained_earnings` (profit or loss carried forward; the account defaults to the one with the role `retained_earnings`), `legal_profit_reserve` or `voluntary_reserve` (equity accounts you name), `dividend_payable` (a liability account you name; a profit only) or `group_dividend` (a dividend to a `shareholder` that is another entity of the organization: the line goes to the account with the role `ic_other_payable`, and when the entry posts the shareholder gets a draft entry to accept, ADR-0025; a profit only)."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Account code in the entity. Required except for `retained_earnings` and `group_dividend` (which takes none). It must be active and not a control account."
          },
          "shareholder": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Shareholder",
            "description": "For `group_dividend` only: the code (or id) of the shareholder entity, which needs an active intercompany relationship with this one."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "The amount, positive, in the functional currency (a decimal string). For a dividend the gross amount."
          },
          "withholding_tax": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "deduct",
                  "notification"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Tax",
            "description": "A dividend of a Swiss entity: `deduct` (the default) books 35 % of the gross dividend as Swiss withholding tax payable (role `withholding_tax_payable`) and the rest as the dividend payable; `notification` (a `group_dividend` to a Swiss shareholder that holds at least 10 %, Art. 26a VStV) books the gross dividend and the tax is declared, not paid. Empty for anything else."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "amount"
        ],
        "title": "Destination"
      },
      "DifferenceLine": {
        "properties": {
          "asset": {
            "type": "string",
            "title": "Asset",
            "description": "Asset code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Asset name."
          },
          "book": {
            "type": "string",
            "title": "Book",
            "description": "Tax book code."
          },
          "carrying_amount": {
            "type": "string",
            "title": "Carrying Amount",
            "description": "Carrying amount in the ledger at the period end (0 if disposed)."
          },
          "tax_base": {
            "type": "string",
            "title": "Tax Base",
            "description": "Cost less the tax book's depreciation to the period end."
          },
          "temporary_difference": {
            "type": "string",
            "title": "Temporary Difference",
            "description": "Carrying amount less tax base: positive is taxable (liability), negative deductible (asset)."
          },
          "deferred_tax": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Deferred Tax",
            "description": "Difference times the tax rate, for the book that carries deferred tax."
          }
        },
        "type": "object",
        "required": [
          "asset",
          "name",
          "book",
          "carrying_amount",
          "tax_base",
          "temporary_difference",
          "deferred_tax"
        ],
        "title": "DifferenceLine"
      },
      "DifferenceReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency of the amounts."
          },
          "period": {
            "$ref": "#/components/schemas/PeriodRef",
            "description": "The period the report is measured at."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/DifferenceLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "One line per asset and tax book."
          },
          "totals": {
            "items": {
              "$ref": "#/components/schemas/BookTotal"
            },
            "type": "array",
            "title": "Totals",
            "description": "One total per tax book."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "period",
          "lines",
          "totals"
        ],
        "title": "DifferenceReport"
      },
      "DimensionAccount": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Account code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name in the user's language."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "`revenue` or `expense`."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Debits in the range, functional currency."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Credits in the range, functional currency."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "The movement in the account's normal direction (credit for revenue, debit for expenses)."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "type",
          "debit",
          "credit",
          "balance"
        ],
        "title": "DimensionAccount"
      },
      "DimensionInput": {
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_]{1,30}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Lower-case letters, digits and `_`, from 2 to 31 characters, starting with a letter; never changes. Omitted: made from the name (`Cost centre` is `cost_centre`)."
          },
          "name": {
            "type": "string",
            "maxLength": 60,
            "minLength": 1,
            "title": "Name",
            "description": "The name shown on screens, at most 60 characters."
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "DimensionInput",
        "examples": [
          {
            "code": "region",
            "name": "Region"
          },
          {
            "name": "Cost centre"
          }
        ]
      },
      "DimensionLine": {
        "properties": {
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "The journal entry (`GET /v1/journal-entries/{id}`)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "The entry's number."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "The entry's date."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "The entry's description."
          },
          "line_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line Description",
            "description": "The line's own text; null when none."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "The line's account code."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "The account's name in the user's language."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency the line was booked in."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Debit less credit in that currency."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Debit in the functional currency."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Credit in the functional currency."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "Every dimension the line names."
          }
        },
        "type": "object",
        "required": [
          "entry_id",
          "number",
          "entry_date",
          "description",
          "line_description",
          "account",
          "account_name",
          "currency",
          "amount",
          "debit",
          "credit",
          "dimensions"
        ],
        "title": "DimensionLine"
      },
      "DimensionLines": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its functional currency."
          },
          "dimension": {
            "type": "string",
            "title": "Dimension",
            "description": "The dimension."
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value",
            "description": "The value; null: the lines that name none."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range, included."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/DimensionLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The posted profit and loss lines, by date and posting order."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "dimension",
          "value",
          "start",
          "end",
          "lines"
        ],
        "title": "DimensionLines"
      },
      "DimensionOut": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The dimension's code, as lines name it: `cost_centre`, `profit_centre`, `project`, or one the organization added."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The dimension's name."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether new lines may name it."
          },
          "values": {
            "items": {
              "$ref": "#/components/schemas/ValueOut"
            },
            "type": "array",
            "title": "Values",
            "description": "Its values, by code, the inactive ones too."
          },
          "required_accounts": {
            "items": {
              "$ref": "#/components/schemas/RequiredAccount"
            },
            "type": "array",
            "title": "Required Accounts",
            "description": "The accounts on which a manual entry or a document must give it."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "active",
          "values",
          "required_accounts"
        ],
        "title": "DimensionOut"
      },
      "DimensionReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its functional currency, which every amount is in."
          },
          "dimension": {
            "type": "string",
            "title": "Dimension",
            "description": "The dimension reported by."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range, included."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/DimensionRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "One row per value with postings in the range, by code, then the row of lines that name no value (`value` null)."
          },
          "revenue": {
            "type": "string",
            "title": "Revenue",
            "description": "Total revenue: that of the profit and loss report."
          },
          "expenses": {
            "type": "string",
            "title": "Expenses",
            "description": "Total expenses: that of the profit and loss report."
          },
          "result": {
            "type": "string",
            "title": "Result",
            "description": "Revenue less expenses: the net income of the range."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "dimension",
          "start",
          "end",
          "rows",
          "revenue",
          "expenses",
          "result"
        ],
        "title": "DimensionReport"
      },
      "DimensionRow": {
        "properties": {
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value",
            "description": "The value's code; null for lines that name none."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The value's name; null for lines that name none."
          },
          "revenue": {
            "type": "string",
            "title": "Revenue",
            "description": "Revenue of the lines that name it."
          },
          "expenses": {
            "type": "string",
            "title": "Expenses",
            "description": "Expenses of the lines that name it."
          },
          "result": {
            "type": "string",
            "title": "Result",
            "description": "Revenue less expenses."
          },
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/DimensionAccount"
            },
            "type": "array",
            "title": "Accounts",
            "description": "The accounts it moved, by code."
          }
        },
        "type": "object",
        "required": [
          "value",
          "name",
          "revenue",
          "expenses",
          "result",
          "accounts"
        ],
        "title": "DimensionRow"
      },
      "DimensionUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 60,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "A new name; omitted: unchanged."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "`false` stops new lines naming it (lines posted with it stay as they are); omitted: unchanged."
          }
        },
        "type": "object",
        "title": "DimensionUpdate",
        "examples": [
          {
            "name": "Cost centre"
          }
        ]
      },
      "DirectDebitExportInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity collecting, e.g. `DE01`."
          },
          "collections": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "maxItems": 5000,
            "minItems": 1,
            "title": "Collections",
            "description": "Ids of the receipts to collect (`GET /v1/entities/{entity}/direct-debits`): posted, not yet sent, each listed once."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "collections"
        ],
        "title": "DirectDebitExportInput",
        "examples": [
          {
            "collections": [
              "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            ],
            "entity": "DE01"
          }
        ]
      },
      "DispatchOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the dispatch."
          },
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice or credit note that was sent."
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "title": "Sent At",
            "description": "When the mail server accepted the message, or when a person recorded the hand-over (UTC)."
          },
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "portal",
              "post",
              "system_email"
            ],
            "title": "Channel",
            "description": "`system_email` (this server sent it) or what a person recorded: `email`, `post`, `portal`, `other`."
          },
          "handed_over_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Handed Over On",
            "description": "The day a person says it was handed over; null for a message of this server."
          },
          "recipients": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recipients",
            "description": "The addresses it was sent to, or the recipient a person recorded."
          },
          "subject": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject",
            "description": "Subject line of the e-mail; null for a recorded hand-over."
          },
          "message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message Id",
            "description": "The `Message-ID` header, to find the mail in a mailbox; null for a recorded hand-over."
          },
          "format": {
            "type": "string",
            "enum": [
              "pdf",
              "xrechnung",
              "zugferd"
            ],
            "title": "Format",
            "description": "`pdf`, `zugferd` or `xrechnung`: the form of the file handed over."
          },
          "attachments": {
            "items": {
              "$ref": "#/components/schemas/AttachmentOut"
            },
            "type": "array",
            "title": "Attachments",
            "description": "What was handed over, with each file's SHA-256: for a message of this server the PDF and, for a German public-sector customer with a Leitweg-ID, the XRechnung XML; for a recorded hand-over the archived file."
          },
          "sent_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Sent By",
            "description": "The actor (`type`, `id`) that sent it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "document_id",
          "sent_at",
          "channel",
          "handed_over_on",
          "recipients",
          "subject",
          "message_id",
          "format",
          "attachments",
          "sent_by"
        ],
        "title": "DispatchOut"
      },
      "Dispatches": {
        "properties": {
          "sending_configured": {
            "type": "boolean",
            "title": "Sending Configured",
            "description": "`false` when this deployment has no mail server, or this is a test copy: `POST .../send` answers 409, and the document is delivered by downloading the PDF."
          },
          "test_copy": {
            "type": "boolean",
            "title": "Test Copy",
            "description": "`true` in a test copy (`POST /v1/test-copies`): it never e-mails customers, who may be real ones copied from the organization it was made from.",
            "default": false
          },
          "suggested_recipient": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suggested Recipient",
            "description": "The address a send without `to` would use; null when the customer has none."
          },
          "default_format": {
            "type": "string",
            "enum": [
              "pdf",
              "zugferd"
            ],
            "title": "Default Format",
            "description": "The format a send without `format` uses: `pdf` (ZUGFeRD stays available on request until the hybrid is validated as PDF/A-3)."
          },
          "allowed_recipients": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Allowed Recipients",
            "description": "The addresses a send may go to: the customer's e-invoice address, e-mail address and contacts' e-mail addresses. Add an address to the customer to use it."
          },
          "zugferd_available": {
            "type": "boolean",
            "title": "Zugferd Available",
            "description": "`true` when the invoice can be output as ZUGFeRD / Factur-X (German entity)."
          },
          "xrechnung_attached": {
            "type": "boolean",
            "title": "Xrechnung Attached",
            "description": "`true` when a send also attaches the XRechnung XML (German entity, customer with a Leitweg-ID)."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/DispatchOut"
            },
            "type": "array",
            "title": "Items",
            "description": "What was sent, oldest first."
          }
        },
        "type": "object",
        "required": [
          "sending_configured",
          "suggested_recipient",
          "default_format",
          "allowed_recipients",
          "zugferd_available",
          "xrechnung_attached",
          "items"
        ],
        "title": "Dispatches",
        "description": "How an invoice can be delivered, and what was already sent."
      },
      "DisposalInput": {
        "properties": {
          "disposal_date": {
            "type": "string",
            "format": "date",
            "title": "Disposal Date",
            "description": "Date of the disposal, ISO 8601; the posting is dated here and its period must be open."
          },
          "proceeds": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Proceeds",
            "description": "Sale proceeds as a decimal string, e.g. \"2500.00\". Default \"0\" (scrapped).",
            "default": "0"
          },
          "proceeds_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proceeds Account",
            "description": "Where proceeds are debited."
          }
        },
        "type": "object",
        "required": [
          "disposal_date"
        ],
        "title": "DisposalInput",
        "examples": [
          {
            "disposal_date": "2026-09-30",
            "proceeds": "2500.00",
            "proceeds_account": "1020"
          }
        ]
      },
      "DocumentAction": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why; kept in the audit trail."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "DocumentAction",
        "examples": [
          {
            "reason": "Entered twice by mistake"
          }
        ]
      },
      "DocumentInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity the document belongs to, e.g. `CH01`."
          },
          "kind": {
            "type": "string",
            "enum": [
              "purchase_bill",
              "purchase_credit_note",
              "sales_credit_note",
              "sales_invoice"
            ],
            "title": "Kind",
            "description": "`sales_invoice`, `sales_credit_note`, `purchase_bill` or `purchase_credit_note`; the sales kinds take a customer as `party`, the purchase kinds a vendor."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Customer or vendor code (or id)."
          },
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "Document date (ISO 8601, e.g. `2026-09-15`): the invoice date. It must fall in an open period for the document to be posted. It is the tax point unless `supply_date` moves it; the VAT rates are those of the date of supply (a credit note takes the rates of the document it credits). Sales invoices and credit notes: default today where the company is. Bills and vendor credit notes: required, the date the vendor printed on it (`422` `document_date_required`)."
          },
          "supply_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supply Date",
            "description": "The date of supply (ISO 8601): when the goods were delivered or the service was performed (Leistungsdatum, date de livraison, data di effettuazione), printed on the invoice; omitted or null: the document date. Where the law of the company's country makes VAT due with the supply (DE, ES, GB; FR and IT for goods), the VAT is reported in the period of the supply, and the VAT rate and the official VAT exchange rate are those of the supply. An invoice issued before the supply (an advance invoice) is reported with its own date. A credit note is reported with its own date whatever its date of supply. Switzerland: VAT is due with the invoice (Art. 40 MWSTG)."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "Due date (ISO 8601). Default: the document date plus the party's `payment_terms_days`, moved by `due_date_convention` if given."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code of the document currency, e.g. `EUR`; default: the party's currency (a credit note takes the currency of the document it credits)."
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number",
            "description": "Vendor's invoice number."
          },
          "credits": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credits",
            "description": "Document this credit note corrects."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text kept on the document."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/DocumentLineInput"
            },
            "type": "array",
            "title": "Lines",
            "description": "The document's lines. At least one, except on a credit note with `credits` set, which then copies the quantities remaining after posted and pending credits. Price corrections or credits without a line link may require explicit lines."
          },
          "source_document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Document Id",
            "description": "Id of the stored original file (e-invoice or captured bill) the document was entered from; shown as `source_file` and downloadable with `GET /v1/documents/{id}/file`."
          },
          "provenance": {
            "additionalProperties": true,
            "type": "object",
            "title": "Provenance",
            "description": "Free-form object stored with the document, e.g. where the data came from. The server adds the reference-data versions and warnings. On a vendor document, `vendor_vat_ids` (a list) gives the VAT ids the document shows: the seller's (BT-31) and its tax representative's (BT-63); one of the company's VAT area tells that VAT the vendor printed may be the company's own VAT, not foreign VAT."
          },
          "payment_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Iban",
            "description": "Bills: the account to pay if not the vendor's IBAN, e.g. a QR-IBAN."
          },
          "payment_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Reference",
            "description": "Bills: the QR reference or ISO 11649 creditor reference to quote."
          },
          "due_date_convention": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "following",
                  "modified_following",
                  "modified_preceding",
                  "preceding"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date Convention",
            "description": "Roll a due date computed from the payment terms onto a business day of the entity's country payment calendar (CH: SIC, euro area: TARGET), e.g. 'following'. Ignored when due_date is given."
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "Invoices: the buyer's reference (XRechnung BT-10); defaults to the customer's Leitweg-ID."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount (Skonto) percent if paid within cash_discount_days, e.g. 2. Default: the party's; 0 for none."
          },
          "cash_discount_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Days",
            "description": "Days from the document date within which the cash discount may be taken, 0 to 365. Give this or `cash_discount_date`, not both."
          },
          "cash_discount_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Date",
            "description": "Instead of days."
          },
          "order_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Reference",
            "description": "Buyer's PO number (BT-13)."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "A discount on the whole document, in percent of the lines after their own discounts (above 0, at most 100). It is split over the lines by what each is worth, so the VAT of each rate goes down by its share. Give this or `discount_amount`, not both."
          },
          "discount_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Amount",
            "description": "A discount on the whole document as an amount in its currency, at most what the lines are worth after their own discounts; split over the lines like `discount_percent`. On a credit note too, only the document discount it gives applies: the share of the credited document's discount comes with each line that credits a line as it was, in that line's own discount (`credits_line`)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "kind",
          "party"
        ],
        "title": "DocumentInput",
        "examples": [
          {
            "document_date": "2026-09-15",
            "entity": "CH01",
            "kind": "sales_invoice",
            "lines": [
              {
                "description": "Consulting September 2026",
                "quantity": "10",
                "unit_price": "180.00"
              }
            ],
            "party": "C-CH"
          }
        ]
      },
      "DocumentLineInput": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text of the line, e.g. `Consulting September 2026`. Required, except on a line that names a `product` (default: the product's name) or credits a line (`credits_line`; default: that line's text)."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Quantity",
            "description": "Quantity as a decimal string, greater than 0; default `1`.",
            "default": "1"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price",
            "description": "Net unit price; negative only on vendor documents (e.g. a discount line). Required, except on a line that names a `product`: left out, it takes the customer's price from its price list in the document's currency, else the product's list price on the document date (`422` `product_unpriced` when it has neither); and on a credit note line with `credits_line`: left out, the line credits that line as it was, at its price and (unless the line gives its own) its discount."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "A discount on the line, in percent of quantity times unit price (at most 100; 0 for none). Give this or `discount_amount`, not both."
          },
          "discount_amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Amount",
            "description": "A discount on the line, as an amount off quantity times unit price in the document currency, at most what the line is worth (0 for none). Give this or `discount_percent`."
          },
          "credits_line": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Credits Line",
            "description": "Credit notes with `credits`: the number of the line of the credited document this line credits. Without a `unit_price` the line credits it as it was: it takes that line's price and its discount with its share of the document discount, in proportion to the quantity it credits (what is left of them when it credits the rest of the line), and returns them as its own `unit_price` and discount, with `as_credited` true when it gave no discount either. To change the quantity of such a line later, send it again without price and discount; sent with them, it credits them as given. With a `unit_price` only the discount the line gives applies; where the credited line had a discount (its own or a share of the document discount) the line must give one (`0` for none), else `422` `credit_discount_required`. The line also takes that line's tax decision as stored (`supply_type`, `rate_type`, `tax_category`, `vat_scope` and the `tax`: treatment, taxing jurisdiction, rates), so it reverses exactly the tax charged; one it states that differs is not taken, with the warning `credit_takes_credited_vat`."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Defaults to the product's revenue account, else the party or entity default."
          },
          "product": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product",
            "description": "Sales documents: code (or id) of an active product of the entity (`GET /v1/products`). The line takes the product's revenue account, `supply_type` and `rate_type` unless it names its own, and its name and price when it gives none (the price in force: `GET /v1/products/{product_id}/price`); the document's `provenance.filled` says what was taken."
          },
          "obligation": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Obligation",
            "description": "Sales documents: id of the performance obligation of an active revenue contract of the same customer and currency that the line bills (`GET /v1/revenue-contracts/{contract_id}`). The line is booked to the contract liability account (the role `contract_liability`), not to revenue: the recognition run makes the revenue (`POST /v1/periods/{period_id}/revenue-recognition`). It takes no `account` of its own, is not a supply of `goods`, and the net billed of the contract never exceeds its transaction price (posting is refused, `422`)."
          },
          "sales_line": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Line",
            "description": "Sales invoices: id of the sales order line the line invoices (`GET /v1/sales-documents/{document}`), of an open order of the same customer and currency. The invoices of an order line never add up to more than was ordered less what was closed (`422`); a draft reserves its quantity until it is voided. Usually set by `POST /v1/sales-documents/{document}/invoice`."
          },
          "delivery_line": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Line",
            "description": "Sales invoices: id of the line of a posted delivery note of the same customer that the line invoices (`GET /v1/delivery-notes/{note_id}`), of the same product. What the invoices of a delivery note line add up to, less what credit notes took back, never exceeds what was delivered less what came back (`422`). The goods left with the delivery note, so the invoice moves no stock. Usually set by `POST /v1/delivery-notes/{note_id}/invoice`. A line of a stock item that names none ships with the invoice: posting the invoice issues the goods (Dr cost of goods sold / Cr inventory)."
          },
          "goods_returned": {
            "type": "boolean",
            "title": "Goods Returned",
            "description": "Sales credit notes: the goods of this line came back. The line names the line it credits (`credits_line`), of a stock item; posting the credit note brings the quantity back into stock at the cost it left with (Dr inventory / Cr cost of goods sold). Without it no stock moves.",
            "default": false
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "Code (or id) of the warehouse the goods come back to (`goods_returned`) or ship from with the invoice (a stock item's invoice line that names no delivery note line); default the entity's default warehouse."
          },
          "supply_type": {
            "type": "string",
            "enum": [
              "electronic_services",
              "goods",
              "services"
            ],
            "title": "Supply Type",
            "description": "`goods`, `services` (default) or `electronic_services`; part of the place-of-supply decision.",
            "default": "services"
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "exempt",
              "parking",
              "reduced",
              "special",
              "standard",
              "super_reduced",
              "zero"
            ],
            "title": "Rate Type",
            "description": "Which VAT rate of the jurisdiction applies: `standard` (default), `reduced`, `super_reduced`, `parking`, `zero`, `special` or `exempt`.",
            "default": "standard"
          },
          "tax_category": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Category",
            "description": "One of the categories of the rate (`GET /v1/entities/{entity}/vat-rate-types`), e.g. `books`: it chooses the rate where the rate type has several (France reduced: 5.5 % or 10 %) and names the kind of an exempt supply (`insurance`). Omit for none."
          },
          "printed_tax_amount": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Printed Tax Amount",
            "description": "VAT shown on a vendor bill; compared with the determined VAT."
          },
          "vat_recovery_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,2}0*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Recovery Percent",
            "description": "Purchase bills and their credit notes: how much of the line's input VAT the company may deduct, in percent (0 to 100, two places), e.g. `0` for a gift whose VAT the law excludes or `50` for a car used half privately. The rest is booked as part of the cost on the line's own account, not as input VAT, so no VAT return reports it. Omit (null) to take the account's `vat_recovery_percent`, else 100. A self-assessed line still owes all of its VAT. Below 100 it is refused (422) on a line without input VAT of our own: a sales line, one outside VAT, foreign VAT booked as cost, US sales or use tax, a Canadian line of several taxes."
          },
          "reverse_charge": {
            "type": "boolean",
            "title": "Reverse Charge",
            "description": "Vendor documents: the vendor invoices under reverse charge (EN 16931 VAT category AE, e.g. UStG §13b), so the VAT is self-assessed at the determined rate.",
            "default": false
          },
          "use_tax": {
            "type": "boolean",
            "title": "Use Tax",
            "description": "A US company's bill line the vendor charged no sales tax on, for something used in the company's own state: the company self-assesses use tax on it at the state's rate and its use tax area's (ADR-0064). Refused on sales documents and for companies outside the US.",
            "default": false
          },
          "vat_scope": {
            "type": "string",
            "enum": [
              "in_scope",
              "outside"
            ],
            "title": "Vat Scope",
            "description": "`in_scope` (default): the tax is determined as usual. `outside`: the line is outside the scope of VAT, like interest and fees for late payment (compensation for damage), a supply within a VAT group or an Organschaft. It needs `vat_scope_reason`, has no tax determination and rate 0, carries no tax tag (so no VAT report or return has it) and prints the remark of its reason in the document's language. It takes no `tax_category`, `printed_tax_amount` or `reverse_charge`, and a document with such a line carries no cash discount.",
            "default": "in_scope"
          },
          "vat_scope_reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "damages",
                  "organschaft",
                  "vat_group"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Scope Reason",
            "description": "Required with `vat_scope` `outside`, refused otherwise: `damages` (compensation for damage), `vat_group` (a supply within a Swiss VAT group, Art. 13 MWSTG) or `organschaft` (an Innenumsatz of a German Organschaft, § 2 para. 2 no. 2 UStG)."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "Dimension code to value code, e.g. `{\"cost_centre\": \"CC-200\", \"project\": \"P-17\"}` (`GET /v1/dimensions`): each an active value, valid on the document date in its company. They go onto the journal lines of the line's amount (not its VAT or the receivable or payable). An account may require a dimension (`required_accounts` of the dimension): the document is then refused at submission without it."
          }
        },
        "type": "object",
        "title": "DocumentLineInput"
      },
      "DocumentLineOut": {
        "properties": {
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Position of the line, from 1."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Text of the line."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity."
          },
          "creditable_quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditable Quantity",
            "description": "Posted invoice or bill detail: quantity remaining to credit, after posted and pending credits. Zero for a fully credited line or a price correction that needs manual credit lines; null when not calculated (including lists)."
          },
          "creditable_tax_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditable Tax Amount",
            "description": "Posted invoice or bill detail: VAT remaining on this line; null when not calculated. A copied vendor credit uses this remaining printed VAT."
          },
          "creditable_discount_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditable Discount Amount",
            "description": "Posted invoice or bill detail: exact discount on the remaining quantity, including the document discount and rounding remainder; null when not calculated. The last credit uses this amount so the parts add up exactly."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net unit price in the document currency."
          },
          "account_id": {
            "type": "string",
            "format": "uuid",
            "title": "Account Id",
            "description": "Id of the revenue or expense account the line is booked to."
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Id",
            "description": "Id of the product a sales line sells (`GET /v1/products`)."
          },
          "obligation_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Obligation Id",
            "description": "Id of the performance obligation of a revenue contract the line bills; the line is then booked to the contract liability account (`GET /v1/revenue-contracts`)."
          },
          "sales_line_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Line Id",
            "description": "Id of the sales order line the line invoices (`GET /v1/sales-documents/{document}`); null for none."
          },
          "credits_line": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credits Line",
            "description": "Credit notes: the number of the line of the credited document this line credits; null for a line of its own."
          },
          "delivery_line_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Line Id",
            "description": "Sales invoices: id of the delivery note line the line invoices (`GET /v1/delivery-notes/{note_id}`); null for none."
          },
          "goods_returned": {
            "type": "boolean",
            "title": "Goods Returned",
            "description": "Sales credit notes: the goods of the line came back into stock (`warehouse_id`), at the cost they left with.",
            "default": false
          },
          "warehouse_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse Id",
            "description": "Of a stock item's line: the warehouse its goods come back to (credit note with `goods_returned`) or ship from with the invoice (an invoice line that names no delivery note line); null otherwise."
          },
          "as_credited": {
            "type": "boolean",
            "title": "As Credited",
            "description": "Credit notes: the line credits the line `credits_line` as it was. It was sent without a price or discount, so it took that line's price and its discount in proportion to its quantity. Sent again that way (no `unit_price`, no discount), it credits a new quantity as it was too. False for a line with a price or discount of its own.",
            "default": false
          },
          "supply_type": {
            "type": "string",
            "title": "Supply Type",
            "description": "`goods`, `services` or `electronic_services`."
          },
          "rate_type": {
            "type": "string",
            "title": "Rate Type",
            "description": "VAT rate type requested for the line, e.g. `standard`."
          },
          "tax_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Category",
            "description": "Named tax category, if one overrides the rate type."
          },
          "use_tax": {
            "type": "boolean",
            "title": "Use Tax",
            "description": "A US company's bill line the vendor charged no sales tax on, for something used in the company's own state: the company self-assesses use tax on it at the state's rate and its use tax area's (ADR-0064). Refused on sales documents and for companies outside the US.",
            "default": false
          },
          "vat_scope": {
            "type": "string",
            "enum": [
              "in_scope",
              "outside"
            ],
            "title": "Vat Scope",
            "description": "`in_scope`, or `outside` for a line outside the scope of VAT (no tax determination, rate 0).",
            "default": "in_scope"
          },
          "vat_scope_reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "damages",
                  "organschaft",
                  "vat_group"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Scope Reason",
            "description": "Why an `outside` line is outside VAT; null for `in_scope`."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "The line discount as a percent of quantity times unit price; null when it was given as an amount, or there is none."
          },
          "discount_amount": {
            "type": "string",
            "title": "Discount Amount",
            "description": "The line discount in the document currency; 0 for none.",
            "default": "0.00"
          },
          "document_discount_amount": {
            "type": "string",
            "title": "Document Discount Amount",
            "description": "The line's share of the document discount, split over the lines by what each is worth after its own discount; 0 for none.",
            "default": "0.00"
          },
          "net_amount": {
            "type": "string",
            "title": "Net Amount",
            "description": "Quantity times unit price, rounded, less the line discount and the line's share of the document discount, in the document currency; the VAT is on it."
          },
          "tax_rate": {
            "type": "string",
            "title": "Tax Rate",
            "description": "VAT rate charged, in percent."
          },
          "tax_amount": {
            "type": "string",
            "title": "Tax Amount",
            "description": "VAT amount of the line in the document currency: on a vendor document, what the vendor charged, also foreign VAT booked as cost (see `tax`)."
          },
          "tax": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax",
            "description": "The tax decision: `treatment`, `liable_party`, `taxing_jurisdiction`, `charged_rate`, `accounted_rate`, `self_assessed`, the rule and its legal `reference`, the reference-data `dataset_version` and its sources. On a bill: treatment `foreign_vat` when the supply is taxed abroad and the vendor's VAT is booked as cost; `foreign_vat` (`amount`, `rate`, `jurisdiction`) on a line self-assessed here whose vendor charged its own country's VAT as well, booked as cost beside it. A Canadian line lists its taxes in `components` (`tax_type` gst, hst, qst, pst or rst, `jurisdiction`, `rate`, `amount`): each is booked and printed on its own."
          },
          "vat_recovery_percent": {
            "type": "string",
            "title": "Vat Recovery Percent",
            "description": "How much of the line's input VAT is deductible, in percent (0 to 100): the line's own, else its account's, else 100. The rest of the VAT is booked as part of the cost on the line's account and no VAT return reports it (ADR-0079). 100 on every line without input VAT of our own (sales, foreign VAT booked as cost, US sales tax).",
            "default": "100"
          },
          "tax_fx_net_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx Net Amount",
            "description": "Net amount at the official VAT exchange rate."
          },
          "tax_fx_tax_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx Tax Amount",
            "description": "VAT at the official VAT exchange rate."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "The line's cost centre, profit centre, project ...: dimension code to value code, as on the journal lines of its amount; empty when none."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "description",
          "quantity",
          "unit_price",
          "account_id",
          "supply_type",
          "rate_type",
          "tax_category",
          "net_amount",
          "tax_rate",
          "tax_amount",
          "tax"
        ],
        "title": "DocumentLineOut"
      },
      "DocumentLink": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the linked document."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number"
        ],
        "title": "DocumentLink"
      },
      "DocumentOut": {
        "properties": {
          "withholding_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Code",
            "description": "Vendor documents: the withholding tax code kept back (`IT-RA-20`, `custom`); null for none."
          },
          "withholding_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Rate",
            "description": "The withholding rate in percent of `withholding_base`."
          },
          "withholding_base": {
            "type": "string",
            "title": "Withholding Base",
            "description": "The net amount before VAT the withholding tax is taken on; 0 for none.",
            "default": "0.00"
          },
          "withholding_amount": {
            "type": "string",
            "title": "Withholding Amount",
            "description": "The withholding tax kept back from the vendor, owed to the tax authority (the account of role `vendor_withholding_payable`). `total` is net plus VAT less it: what the vendor is paid.",
            "default": "0.00"
          },
          "creditable_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditable Amount",
            "description": "Posted invoice or bill detail: document amount left to credit after posted and pending credits, independently of receipts or payments; null in lists."
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the document."
          },
          "entity_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entity Id",
            "description": "Id of the entity (company) the document belongs to; its functional currency and chart of accounts are the ones the amounts and lines refer to."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`sales_invoice`, `sales_credit_note`, `purchase_bill` or `purchase_credit_note`."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer or vendor."
          },
          "party_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Code",
            "description": "Code of the customer or vendor, e.g. `C-DE`."
          },
          "party_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Name",
            "description": "Name of the customer or vendor."
          },
          "party_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Status",
            "description": "The customer's or vendor's status: `active`, or `draft` until a second person activates it (a draft party's documents are neither submitted nor posted)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Gap-free document number such as `INV-2026-000001`, assigned when the document is posted; null before."
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number",
            "description": "The vendor's own invoice number (bills)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval` (waiting for a second person), `posted`, `rejected` (an approver refused it; it can be reopened) or `void`."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Document date (ISO 8601); the tax point unless `supply_date` moves it."
          },
          "supply_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supply Date",
            "description": "The date of supply when it is not the document date (it then decides the VAT period where the law of the company's country says so); null: the document date."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date (ISO 8601)."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the document; the amounts below are in it."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Sum of the line net amounts, in the document currency."
          },
          "tax_total": {
            "type": "string",
            "title": "Tax Total",
            "description": "Sum of the line VAT amounts, in the document currency."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "What is owed: net plus VAT, less withholding tax."
          },
          "functional_total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Functional Total",
            "description": "The total in the entity's functional currency as booked; null until posted."
          },
          "credits_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credits Id",
            "description": "Credit notes: id of the document this note corrects."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "Id of the journal entry created when the document was submitted (posted, or waiting for approval); null for a draft."
          },
          "source_document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Document Id",
            "description": "Id of the stored original file the document was entered from."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text kept on the document."
          },
          "legal_notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Legal Notes",
            "description": "Legal notes the document carries for its tax treatment (reverse charge, exempt intra-Community supply) with their legal reference."
          },
          "payment_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Iban",
            "description": "Bills: the account to pay if not the vendor's own IBAN."
          },
          "payment_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Reference",
            "description": "Bills: the QR or creditor reference to quote when paying."
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "The buyer's reference printed on the invoice (XRechnung BT-10)."
          },
          "order_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Reference",
            "description": "The buyer's purchase order number (EN 16931 BT-13)."
          },
          "open_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Open Amount",
            "description": "Posted documents: the amount not yet settled by payments or credit notes (pending ones included); 0 when paid. null before posting."
          },
          "payment_blocked": {
            "type": "boolean",
            "title": "Payment Blocked",
            "description": "A bill blocked for payment: its variance against its purchase order waits for a second person's approval (`GET /v1/documents/{document_id}/match`); proposals leave it out and payments refuse it until then.",
            "default": false
          },
          "tax_fx": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx",
            "description": "Official VAT exchange rate for the tax point (CH: BAZG/ESTV, DE: BMF): series, rate, quotation, period or fixing date, and status 'final' or 'provisional' (not published yet; the VAT return looks it up)."
          },
          "tax_fx_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx Rate",
            "description": "The official VAT exchange rate to the functional currency, when the document is in a foreign currency."
          },
          "tax_fx_net_total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx Net Total",
            "description": "Net total at the official VAT exchange rate."
          },
          "tax_fx_tax_total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx Tax Total",
            "description": "VAT total at the official VAT exchange rate."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount (Skonto) terms: percent off the gross total."
          },
          "cash_discount_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Date",
            "description": "The last day the cash discount may be taken."
          },
          "cash_discount_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Amount",
            "description": "The cash discount on the gross total."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "The document discount in percent; null when it was given as an amount, or there is none."
          },
          "discount_amount": {
            "type": "string",
            "title": "Discount Amount",
            "description": "The document discount, the sum of the lines' shares; 0 for none. `net_total` is after it.",
            "default": "0.00"
          },
          "provenance": {
            "additionalProperties": true,
            "type": "object",
            "title": "Provenance",
            "description": "How the document came about: its origin, reference-data versions used for the tax determination and warnings (e.g. printed VAT that differs from the determined VAT)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "The actor (`type`, `id`) that created the document."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "When the document was created (UTC)."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "Raised on every change; the ETag names it.",
            "default": 1
          },
          "missing_content": {
            "items": {
              "$ref": "#/components/schemas/ContentGap"
            },
            "type": "array",
            "title": "Missing Content",
            "description": "Sales invoices and credit notes: the legally required content that the entity's or the customer's record still lacks (empty when complete). Printing, sending and e-invoicing refuse the document with 409 until it is empty; on a draft or a preview it is a warning."
          },
          "source_file": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SourceFileOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The stored original file, if any; the bytes are `GET /v1/documents/{id}/file`."
          },
          "ic": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IcBlock"
              },
              {
                "type": "null"
              }
            ],
            "description": "Intercompany: the link of a document whose customer or vendor is another entity of the organization (origin or mirror, its status, the document at the other end); null for any other document."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/DocumentLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The document's lines with the tax determined for each."
          },
          "delivery_notes": {
            "items": {
              "$ref": "#/components/schemas/DocumentLink"
            },
            "type": "array",
            "title": "Delivery Notes",
            "description": "Sales invoices: the delivery notes its lines invoice."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity_id",
          "kind",
          "party_id",
          "number",
          "external_number",
          "status",
          "document_date",
          "due_date",
          "currency",
          "net_total",
          "tax_total",
          "total",
          "functional_total",
          "credits_id",
          "journal_entry_id",
          "source_document_id",
          "notes",
          "legal_notes",
          "provenance",
          "created_by"
        ],
        "title": "DocumentOut"
      },
      "DocumentRef": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the document."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity whose books hold it."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number; null while it is a draft."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`sales_invoice`, `sales_credit_note`, `purchase_bill` ..."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `posted`, `rejected`, `void`."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Its date."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "The customer or vendor, which is the other entity."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Gross total in the document currency."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "entity",
          "number",
          "kind",
          "status",
          "document_date",
          "party_code",
          "total"
        ],
        "title": "DocumentRef"
      },
      "DocumentResult": {
        "properties": {
          "document": {
            "$ref": "#/components/schemas/DocumentOut",
            "description": "The document as stored."
          },
          "submit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "How the submission went (`policy`: `allow` or `require_approval`, entry id, `approval_id`); null when the document was created with `submit=false`."
          }
        },
        "type": "object",
        "required": [
          "document",
          "submit"
        ],
        "title": "DocumentResult"
      },
      "DocumentSides": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The document currency."
          },
          "a": {
            "type": "string",
            "title": "A",
            "description": "What `entity_a` holds towards `entity_b` in it, signed debit less credit."
          },
          "b": {
            "type": "string",
            "title": "B",
            "description": "What `entity_b` holds towards `entity_a`, signed the same way."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "a",
          "b"
        ],
        "title": "DocumentSides"
      },
      "DocumentUpdate": {
        "properties": {
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Customer or vendor code (or id)."
          },
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "New document date (ISO 8601); the due date follows unless given. `null` is refused."
          },
          "supply_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supply Date",
            "description": "The date of supply (ISO 8601): when the goods were delivered or the service was performed (Leistungsdatum, date de livraison, data di effettuazione), printed on the invoice; omitted or null: the document date. Where the law of the company's country makes VAT due with the supply (DE, ES, GB; FR and IT for goods), the VAT is reported in the period of the supply, and the VAT rate and the official VAT exchange rate are those of the supply. An invoice issued before the supply (an advance invoice) is reported with its own date. A credit note is reported with its own date whatever its date of supply. Switzerland: VAT is due with the invoice (Art. 40 MWSTG). `null` clears it (the document date)."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "New due date (ISO 8601); `null` recomputes it from the payment terms."
          },
          "due_date_convention": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "following",
                  "modified_following",
                  "modified_preceding",
                  "preceding"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date Convention",
            "description": "Moves a due date computed from the payment terms onto a business day of the entity's country calendar (CH: SIC, euro area: TARGET): `following`, `modified_following`, `preceding` or `modified_preceding`. Ignored when `due_date` is given."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency code, e.g. `EUR`."
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number",
            "description": "Vendor's invoice number."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text kept on the document; `null` clears it."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/DocumentLineInput"
                },
                "type": "array",
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "The new lines; they replace all existing lines (at least one). `null` or omitted keeps the lines."
          },
          "payment_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Iban",
            "description": "Bills: the account to pay if it is not the vendor's own IBAN, e.g. a QR-IBAN printed on the bill. It must be one of the vendor's confirmed accounts before a payment to it can be released."
          },
          "payment_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Reference",
            "description": "Bills: the QR reference (27 digits) or ISO 11649 creditor reference (`RF...`) printed on the bill, quoted when paying. A QR reference needs a QR-IBAN."
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "XRechnung BT-10."
          },
          "order_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Reference",
            "description": "The buyer's purchase order number (EN 16931 BT-13)."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount (Skonto) percent; 0 for none."
          },
          "cash_discount_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Days",
            "description": "Days from the document date within which the cash discount may be taken, 0 to 365. Give this or `cash_discount_date`, not both."
          },
          "cash_discount_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Date",
            "description": "Last day the cash discount may be taken (ISO 8601, not before the document date), instead of `cash_discount_days`."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "A discount on the whole document in percent; it replaces any document discount. `null` removes the document discount."
          },
          "discount_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Amount",
            "description": "A discount on the whole document as an amount; it replaces any document discount. `null` removes the document discount."
          }
        },
        "type": "object",
        "title": "DocumentUpdate",
        "description": "Changes to a draft. Omitted fields keep their value; ``null`` clears an optional one.\n\n``lines`` replaces every line. The tax of every line is determined again, also when\nonly the party or the date changes. Without ``due_date``, a new date or party\nrecomputes the due date from the payment terms; without ``currency``, a new party\nbrings its currency.",
        "examples": [
          {
            "due_date": "2026-10-31",
            "lines": [
              {
                "description": "Consulting September 2026",
                "quantity": "12",
                "unit_price": "180.00"
              }
            ],
            "notes": "Payable within 45 days."
          }
        ]
      },
      "DoubtfulInput": {
        "properties": {
          "percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Percent",
            "description": "The share of what is open on the invoice the specific allowance covers (100: nothing is expected to come in)."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why the invoice is doubtful (optional)."
          }
        },
        "type": "object",
        "required": [
          "percent"
        ],
        "title": "DoubtfulInput",
        "examples": [
          {
            "note": "Dispute",
            "percent": "50"
          }
        ]
      },
      "DoubtfulOut": {
        "properties": {
          "percent": {
            "type": "string",
            "title": "Percent",
            "description": "The share of what is open on the invoice the specific allowance covers (100: nothing is expected to come in)."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why the invoice is doubtful (optional)."
          },
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Number of the invoice."
          },
          "marked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Marked At",
            "description": "When it was marked doubtful (UTC)."
          }
        },
        "type": "object",
        "required": [
          "percent",
          "document_id",
          "document_number",
          "marked_at"
        ],
        "title": "DoubtfulOut",
        "examples": [
          {
            "note": "Dispute",
            "percent": "50"
          }
        ]
      },
      "DraftUpdate": {
        "properties": {
          "body": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100000,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Body",
            "description": "The reply's new text."
          },
          "to": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 10
              },
              {
                "type": "null"
              }
            ],
            "title": "To",
            "description": "Its recipients: the requester's, the contact's or the customer's addresses."
          }
        },
        "type": "object",
        "title": "DraftUpdate",
        "examples": [
          {
            "body": "Dear Ms Muster,\n\nthe parcel left today."
          }
        ]
      },
      "DunningBlockInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the reminders stop."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "DunningBlockInput",
        "examples": [
          {
            "reason": "The customer disputes the delivered quantity"
          }
        ]
      },
      "DunningBlockOut": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Invoice number."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why the reminders stop."
          },
          "blocked_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Blocked By",
            "description": "Who stopped them: type, id and name."
          },
          "blocked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Blocked At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "reason",
          "blocked_by",
          "blocked_at"
        ],
        "title": "DunningBlockOut",
        "description": "The reminders of an invoice are stopped (for instance while the customer disputes it)."
      },
      "DunningBlockState": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "block": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DunningBlockOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The stop while it holds; null when reminders go out as usual."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "block"
        ],
        "title": "DunningBlockState",
        "description": "Whether the reminders of an invoice are stopped."
      },
      "DunningLevelOut": {
        "properties": {
          "level": {
            "type": "integer",
            "title": "Level",
            "description": "1 payment reminder, 2 second reminder, 3 final reminder."
          },
          "days_after": {
            "type": "integer",
            "title": "Days After",
            "description": "Level 1: days after the due date; later levels: days after the previous letter was handed over."
          },
          "deadline_days": {
            "type": "integer",
            "title": "Deadline Days",
            "description": "Days the letter gives to pay, from its day."
          }
        },
        "type": "object",
        "required": [
          "level",
          "days_after",
          "deadline_days"
        ],
        "title": "DunningLevelOut",
        "description": "One level of reminder and when it is due."
      },
      "EInvoiceResult": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "invalid",
              "needs_review",
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "`draft`, `pending_approval` or `posted` (the bill was created), `invalid` (a fatal rule is broken; stored but not booked) or `needs_review` (unknown vendor with `create_vendor=false`, or a negative total)."
          },
          "valid": {
            "type": "boolean",
            "title": "Valid",
            "description": "`true` when no fatal rule is broken."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Short name of what was read."
          },
          "profile": {
            "type": "string",
            "title": "Profile",
            "description": "The profile or specification the invoice declares."
          },
          "syntax": {
            "type": "string",
            "title": "Syntax",
            "description": "`CII` or `UBL`."
          },
          "container": {
            "type": "string",
            "title": "Container",
            "description": "`xml` or `pdf`."
          },
          "violations": {
            "items": {
              "$ref": "#/components/schemas/Violation"
            },
            "type": "array",
            "title": "Violations",
            "description": "The rules the invoice breaks, by rule id."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "Things to review on the bill, e.g. VAT that differs from the determined VAT or a new draft vendor."
          },
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the stored original file."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the file, hex."
          },
          "bill_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bill Id",
            "description": "Id of the draft bill or vendor credit note that was created."
          },
          "bill_kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bill Kind",
            "description": "`purchase_bill` or `purchase_credit_note`."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "Id of the approval request when the bill waits for approval."
          },
          "vendor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/EInvoiceVendor"
              },
              {
                "type": "null"
              }
            ],
            "description": "The vendor the bill was assigned to."
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Gross total of the bill."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency of the bill."
          },
          "invoice": {
            "$ref": "#/components/schemas/Invoice",
            "description": "The invoice in EN 16931 terms."
          }
        },
        "type": "object",
        "required": [
          "status",
          "valid",
          "label",
          "profile",
          "syntax",
          "container",
          "violations",
          "warnings",
          "document_id",
          "sha256",
          "invoice"
        ],
        "title": "EInvoiceResult"
      },
      "EInvoiceVendor": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Vendor code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Vendor name."
          },
          "matched_by": {
            "type": "string",
            "enum": [
              "created",
              "given",
              "iban",
              "vat_number"
            ],
            "title": "Matched By",
            "description": "`vat_number`, `iban`, `created` (a new draft vendor) or `given`."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`active` or `draft`."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "matched_by",
          "status"
        ],
        "title": "EInvoiceVendor"
      },
      "EliminationLine": {
        "properties": {
          "rule": {
            "type": "string",
            "title": "Rule",
            "description": "The rule of the line: `E1` to `E7`.",
            "default": ""
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The entity whose amount the line reverses (for E4, E5 and E7 the subsidiary, or the parent on the investment line)."
          },
          "partner": {
            "type": "string",
            "title": "Partner",
            "description": "Its group partner."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "The account reversed; null for the residual of the pair."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The account's name, or what the residual is."
          },
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The group report line it is added to."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Debit in the reporting currency."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Credit in the reporting currency."
          },
          "amount_local": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount Local",
            "description": "The amount reversed in the entity's functional currency; null for the residual."
          },
          "rate_kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Kind",
            "description": "`closing` (a balance), `average` (income or expense), `historical` (the equity a dividend debited, at the rate of its day), `none` (the reporting currency) or null (the residual)."
          },
          "rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate",
            "description": "The rate, or the effective rate over several months."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "partner",
          "account",
          "name",
          "report_line",
          "debit",
          "credit",
          "amount_local",
          "rate_kind",
          "rate"
        ],
        "title": "EliminationLine"
      },
      "EliminationPair": {
        "properties": {
          "rule": {
            "type": "string",
            "enum": [
              "E1",
              "E2",
              "E3",
              "E6"
            ],
            "title": "Rule",
            "description": "`E1` intragroup balances (IFRS 10.B86(c), section 303 HGB), `E2` intragroup loans, `E3` intragroup income and expense (IFRS 10.B86(c), section 305 HGB) or `E6` intragroup dividends."
          },
          "entity_a": {
            "type": "string",
            "title": "Entity A",
            "description": "One entity of the pair (the first by code)."
          },
          "entity_b": {
            "type": "string",
            "title": "Entity B",
            "description": "The other."
          },
          "documents": {
            "items": {
              "$ref": "#/components/schemas/DocumentSides"
            },
            "type": "array",
            "title": "Documents",
            "description": "Per document currency what each side holds: the two agree when they add to zero."
          },
          "agreed": {
            "type": "boolean",
            "title": "Agreed",
            "description": "True when the sides agree in every document currency."
          },
          "residual": {
            "type": "string",
            "title": "Residual",
            "description": "What the reversal of both sides leaves in the reporting currency, signed debit less credit; zero when they cancel to the cent."
          },
          "treatment": {
            "type": "string",
            "enum": [
              "cash_in_transit",
              "none",
              "profit_or_loss",
              "translation_reserve",
              "unreconciled"
            ],
            "title": "Treatment",
            "description": "Where the residual went: `profit_or_loss` (E1 or E2, agreed: the exchange difference on an intragroup monetary item stays in profit or loss, IAS 21.45), `translation_reserve` (E3 or E6, agreed: the two sides translated at different rates, IAS 21.41; E2 of a loan that is part of the net investment, IAS 21.32), `cash_in_transit` (E1: the sides disagree only by payments one side booked and the other not yet: the line cash in transit and the warning `ic_cash_in_transit`), `unreconciled` (the sides disagree: a line of its own and the exception `ic_difference`) or `none`."
          },
          "in_transit": {
            "type": "string",
            "title": "In Transit",
            "description": "The cash in transit of `cash_in_transit` in the reporting currency (each document currency at the closing rate), signed debit less credit; zero otherwise."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/EliminationLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines of the pair's elimination."
          }
        },
        "type": "object",
        "required": [
          "rule",
          "entity_a",
          "entity_b",
          "documents",
          "agreed",
          "residual",
          "treatment",
          "in_transit",
          "lines"
        ],
        "title": "EliminationPair"
      },
      "EndpointInput": {
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 500,
            "minLength": 9,
            "title": "Url",
            "description": "Where events are sent (`https://`; a public address, never a private, loopback or link-local one)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What the receiving system is, for people."
          },
          "event_types": {
            "items": {
              "anyOf": [
                {
                  "type": "string",
                  "enum": [
                    "bill.posted",
                    "case.closed",
                    "case.created",
                    "credit_note.posted",
                    "deal.created",
                    "deal.lost",
                    "deal.won",
                    "invoice.posted",
                    "lead.converted",
                    "lead.created",
                    "payment.received",
                    "payment.sent",
                    "quote.accepted",
                    "quote.declined",
                    "subscription.activated",
                    "subscription.cancelled",
                    "task.completed",
                    "task.created",
                    "vendor_credit.posted"
                  ]
                },
                {
                  "type": "string",
                  "const": "*"
                }
              ]
            },
            "type": "array",
            "minItems": 1,
            "title": "Event Types",
            "description": "The events to send; `*` for every event, also those added later."
          }
        },
        "type": "object",
        "required": [
          "url",
          "event_types"
        ],
        "title": "EndpointInput",
        "examples": [
          {
            "description": "Order system",
            "event_types": [
              "invoice.posted",
              "payment.received"
            ],
            "url": "https://hooks.example.com/stabiso"
          }
        ]
      },
      "EndpointOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The endpoint's id."
          },
          "url": {
            "type": "string",
            "title": "Url",
            "description": "Where events are sent."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What the receiving system is."
          },
          "event_types": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Event Types",
            "description": "The events it gets; `*` for every event."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled"
            ],
            "title": "Status",
            "description": "`active` sends; `disabled` keeps what waits and sends nothing."
          },
          "disabled_reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "by_person",
                  "failing"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Disabled Reason",
            "description": "`failing`: the system stopped it after it kept failing for a day."
          },
          "failures_in_row": {
            "type": "integer",
            "title": "Failures In Row",
            "description": "Attempts that failed since the last success."
          },
          "last_success_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Success At",
            "description": "The last delivered attempt."
          },
          "last_failure_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Failure At",
            "description": "The last failed attempt."
          },
          "waiting": {
            "type": "integer",
            "title": "Waiting",
            "description": "Deliveries still to go out (or to try again)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who added it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was added."
          },
          "secret": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Secret",
            "description": "The signing secret (`whsec_...`): only in the answer that made or rotated it, never again."
          }
        },
        "type": "object",
        "required": [
          "id",
          "url",
          "description",
          "event_types",
          "status",
          "disabled_reason",
          "failures_in_row",
          "last_success_at",
          "last_failure_at",
          "waiting",
          "created_by",
          "created_at"
        ],
        "title": "EndpointOut"
      },
      "EndpointUpdate": {
        "properties": {
          "url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 9
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "A new address (as on create)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "A new description."
          },
          "event_types": {
            "anyOf": [
              {
                "items": {
                  "anyOf": [
                    {
                      "type": "string",
                      "enum": [
                        "bill.posted",
                        "case.closed",
                        "case.created",
                        "credit_note.posted",
                        "deal.created",
                        "deal.lost",
                        "deal.won",
                        "invoice.posted",
                        "lead.converted",
                        "lead.created",
                        "payment.received",
                        "payment.sent",
                        "quote.accepted",
                        "quote.declined",
                        "subscription.activated",
                        "subscription.cancelled",
                        "task.completed",
                        "task.created",
                        "vendor_credit.posted"
                      ]
                    },
                    {
                      "type": "string",
                      "const": "*"
                    }
                  ]
                },
                "type": "array",
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Event Types",
            "description": "The new list of events; `*` for every event."
          },
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "active",
                  "disabled"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "`disabled` stops sending (what waits is kept); `active` starts again and sends what waited."
          }
        },
        "type": "object",
        "title": "EndpointUpdate",
        "examples": [
          {
            "status": "disabled"
          }
        ]
      },
      "EntityDetailOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the entity."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The entity code, e.g. `CH01`; the `{entity}` of other operations."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 code of the state or canton, e.g. `DE-BY`; null if none."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "ISO 4217 code of the currency the books are kept in."
          },
          "fiscal_year_start_month": {
            "type": "integer",
            "title": "Fiscal Year Start Month",
            "description": "Month the fiscal year starts, 1 to 12."
          },
          "framework": {
            "type": "string",
            "title": "Framework",
            "description": "Accounting framework: `ifrs`, `us_gaap` or `local`."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "The entity's VAT number; null if not set."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the address; null if not set."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the address; null if not set."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address; null if not set."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address; null if not set."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Seller contact name on e-invoices; null if not set."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "Seller contact phone on e-invoices; null if not set."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "Seller contact email on e-invoices; null if not set."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "Seller electronic address on e-invoices; null if not set."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "Code of the electronic address scheme (EAS), e.g. `EM`; null if not set."
          },
          "posting_approval_limit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Approval Limit",
            "description": "The posting approval limit in the functional currency: whatever a person posts (a manual journal, a bill, an invoice, a payment, a refund, a VAT settlement, a revaluation, a depreciation run) whose functional amount is above it waits for a second person, and so does its reversal. A new company starts at about CHF 100,000 in its currency as a round figure (100000.00 CHF, EUR, USD, GBP or CAD, 1000000.00 SEK, 15000000 JPY). Null: no limit."
          },
          "industry": {
            "type": "string",
            "enum": [
              "ecommerce",
              "general",
              "hospitality",
              "manufacturing",
              "retail",
              "services",
              "trade"
            ],
            "title": "Industry",
            "description": "The company's industry (`GET /v1/industries`): `general`, `hospitality`, `services`, `trade`, `retail`, `ecommerce` or `manufacturing`. It puts the screens of the industry first in the app's menu and on its Home; it switches nothing off, and every operation works the same in every industry.",
            "default": "general"
          },
          "posting_limit_request": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PostingLimitRequest"
              },
              {
                "type": "null"
              }
            ],
            "description": "The request to raise or remove `posting_approval_limit` that waits for a second person; null when none waits."
          },
          "time_zone": {
            "type": "string",
            "title": "Time Zone",
            "description": "The IANA time zone the entity's days are counted in, e.g. `Europe/Zurich`: today, the default date of its documents and the latest day a check accepts are the day it is there (its state's or province's in the United States and Canada).",
            "readOnly": true
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "country",
          "subdivision",
          "functional_currency",
          "fiscal_year_start_month",
          "framework",
          "vat_number",
          "time_zone"
        ],
        "title": "EntityDetailOut",
        "description": "One entity, with what waits for a second person about it."
      },
      "EntityInput": {
        "properties": {
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the entity's address, at most 70 characters."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the address, at most 16 characters."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address, at most 16 characters."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address, at most 35 characters."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Seller contact (BT-41)."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "Seller contact phone (BT-42)."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "Seller contact email (BT-43)."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "Seller electronic address (BT-34); defaults to contact_email."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "EAS code, e.g. EM (email), 9930 (German VAT id), 0204."
          },
          "code": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]{2,20}$",
            "title": "Code",
            "description": "Short unique code, 2 to 20 characters of A-Z, 0-9, `_` and `-`, e.g. `CH01`; it names the entity in every URL."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name, e.g. `Demo AG`."
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Z]{2}$",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code, e.g. `CH` or `DE`; decides the VAT rules."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 code of the state or canton, e.g. `DE-BY`; null when omitted."
          },
          "functional_currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Functional Currency",
            "description": "ISO 4217 code of the currency the books are kept in, e.g. `CHF`. Cannot be changed later. Omitted: the currency of its country (422 `entity_currency_needed` where that is not known)."
          },
          "fiscal_year_start_month": {
            "type": "integer",
            "maximum": 12.0,
            "minimum": 1.0,
            "title": "Fiscal Year Start Month",
            "description": "Month the fiscal year starts, 1 to 12; default 1 (January).",
            "default": 1
          },
          "framework": {
            "type": "string",
            "enum": [
              "ifrs",
              "local",
              "us_gaap"
            ],
            "title": "Framework",
            "description": "Accounting framework: `ifrs` (default), `us_gaap` or `local`.",
            "default": "ifrs"
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "The entity's VAT number, e.g. `CHE-123.456.788 MWST` or `DE123456788`; null when omitted. For a Swiss or German entity its format is checked (422); it is printed on invoices and is required on them when the entity is VAT-registered."
          },
          "chart": {
            "type": "string",
            "title": "Chart",
            "description": "Chart template id (`GET /v1/charts`), e.g. `ch_kmu`; default `ifrs_generic`. `GET /v1/charts?country=` marks the country's standard chart, which the operator's provisioning uses.",
            "default": "ifrs_generic"
          },
          "fiscal_years": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Fiscal Years",
            "description": "Years to open periods for."
          },
          "fiscal_calendar": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FiscalCalendar"
              },
              {
                "type": "null"
              }
            ],
            "description": "Calendar for those years (default: twelve calendar months)."
          },
          "industry": {
            "type": "string",
            "enum": [
              "ecommerce",
              "general",
              "hospitality",
              "manufacturing",
              "retail",
              "services",
              "trade"
            ],
            "title": "Industry",
            "description": "The company's industry (`GET /v1/industries`): `general`, `hospitality`, `services`, `trade`, `retail`, `ecommerce` or `manufacturing`. It puts the screens of the industry first in the app's menu and on its Home; it switches nothing off, and every operation works the same in every industry. Default `general`.",
            "default": "general"
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "country"
        ],
        "title": "EntityInput",
        "examples": [
          {
            "building_number": "10",
            "chart": "ch_kmu",
            "code": "CH02",
            "country": "CH",
            "fiscal_years": [
              2026
            ],
            "functional_currency": "CHF",
            "name": "Demo Services AG",
            "postal_code": "8001",
            "street": "Bahnhofstrasse",
            "town": "Zurich",
            "vat_number": "CHE-123.456.788 MWST"
          }
        ]
      },
      "EntityOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the entity."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The entity code, e.g. `CH01`; the `{entity}` of other operations."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 code of the state or canton, e.g. `DE-BY`; null if none."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "ISO 4217 code of the currency the books are kept in."
          },
          "fiscal_year_start_month": {
            "type": "integer",
            "title": "Fiscal Year Start Month",
            "description": "Month the fiscal year starts, 1 to 12."
          },
          "framework": {
            "type": "string",
            "title": "Framework",
            "description": "Accounting framework: `ifrs`, `us_gaap` or `local`."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "The entity's VAT number; null if not set."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the address; null if not set."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the address; null if not set."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address; null if not set."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address; null if not set."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Seller contact name on e-invoices; null if not set."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "Seller contact phone on e-invoices; null if not set."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "Seller contact email on e-invoices; null if not set."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "Seller electronic address on e-invoices; null if not set."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "Code of the electronic address scheme (EAS), e.g. `EM`; null if not set."
          },
          "posting_approval_limit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Approval Limit",
            "description": "The posting approval limit in the functional currency: whatever a person posts (a manual journal, a bill, an invoice, a payment, a refund, a VAT settlement, a revaluation, a depreciation run) whose functional amount is above it waits for a second person, and so does its reversal. A new company starts at about CHF 100,000 in its currency as a round figure (100000.00 CHF, EUR, USD, GBP or CAD, 1000000.00 SEK, 15000000 JPY). Null: no limit."
          },
          "industry": {
            "type": "string",
            "enum": [
              "ecommerce",
              "general",
              "hospitality",
              "manufacturing",
              "retail",
              "services",
              "trade"
            ],
            "title": "Industry",
            "description": "The company's industry (`GET /v1/industries`): `general`, `hospitality`, `services`, `trade`, `retail`, `ecommerce` or `manufacturing`. It puts the screens of the industry first in the app's menu and on its Home; it switches nothing off, and every operation works the same in every industry.",
            "default": "general"
          },
          "time_zone": {
            "type": "string",
            "title": "Time Zone",
            "description": "The IANA time zone the entity's days are counted in, e.g. `Europe/Zurich`: today, the default date of its documents and the latest day a check accepts are the day it is there (its state's or province's in the United States and Canada).",
            "readOnly": true
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "country",
          "subdivision",
          "functional_currency",
          "fiscal_year_start_month",
          "framework",
          "vat_number",
          "time_zone"
        ],
        "title": "EntityOut"
      },
      "EntityRollForward": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its functional currency."
          },
          "start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start",
            "description": "The date it is consolidated from."
          },
          "opening_reserve": {
            "type": "string",
            "title": "Opening Reserve",
            "description": "The reserve at the start: zero in this version."
          },
          "opening_net_assets": {
            "type": "string",
            "title": "Opening Net Assets",
            "description": "Net assets at the start, in the functional currency."
          },
          "opening_rate": {
            "type": "string",
            "title": "Opening Rate",
            "description": "The historical rate at the start."
          },
          "closing_rate": {
            "type": "string",
            "title": "Closing Rate",
            "description": "The closing rate of the month of the group date."
          },
          "opening_effect": {
            "type": "string",
            "title": "Opening Effect",
            "description": "Net assets at the start x (closing rate - historical rate)."
          },
          "results": {
            "items": {
              "$ref": "#/components/schemas/RollForwardEffect"
            },
            "type": "array",
            "title": "Results",
            "description": "The effect of each month's profit."
          },
          "movements": {
            "items": {
              "$ref": "#/components/schemas/RollForwardEffect"
            },
            "type": "array",
            "title": "Movements",
            "description": "The effect of each equity movement."
          },
          "rounding": {
            "type": "string",
            "title": "Rounding",
            "description": "The sum of the rounding residuals of the translated amounts (each rounded to the minor unit; rounded less exact, signed like the amount), exact: what rounding added to the balancing amount. Zero when every translated amount is exact."
          },
          "closing_reserve": {
            "type": "string",
            "title": "Closing Reserve",
            "description": "The reserve at the group date by the roll-forward, rounded to the minor unit for display (credit positive; a debit reserve is negative)."
          },
          "translated_reserve": {
            "type": "string",
            "title": "Translated Reserve",
            "description": "The balancing amount of the translated trial balance, same sign."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`translated_reserve` less the roll-forward (unrounded) less `rounding`, computed exactly: zero, or the run has the blocking exception `cta_unreconciled`."
          },
          "reconciled": {
            "type": "boolean",
            "title": "Reconciled",
            "description": "True when `difference` is exactly zero. There is no tolerance."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "start",
          "opening_reserve",
          "opening_net_assets",
          "opening_rate",
          "closing_rate",
          "opening_effect",
          "results",
          "movements",
          "rounding",
          "closing_reserve",
          "translated_reserve",
          "difference",
          "reconciled"
        ],
        "title": "EntityRollForward"
      },
      "EntitySummary": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The entity's code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "ISO 4217 code of the books' currency."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "country",
          "functional_currency"
        ],
        "title": "EntitySummary"
      },
      "EntityUpdate": {
        "properties": {
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the address, at most 70 characters; omit or null to keep it."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number, at most 16 characters; omit or null to keep it."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code, at most 16 characters; omit or null to keep it."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town, at most 35 characters; omit or null to keep it."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Seller contact (BT-41)."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "Seller contact phone (BT-42)."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "Seller contact email (BT-43)."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "Seller electronic address (BT-34); defaults to contact_email."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "EAS code, e.g. EM (email), 9930 (German VAT id), 0204."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New legal name; omit or null to keep it."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "New VAT number (format checked for a Swiss or German entity, 422); omit or null to keep it."
          },
          "industry": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "ecommerce",
                  "general",
                  "hospitality",
                  "manufacturing",
                  "retail",
                  "services",
                  "trade"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Industry",
            "description": "The company's industry (`GET /v1/industries`): `general`, `hospitality`, `services`, `trade`, `retail`, `ecommerce` or `manufacturing`. It puts the screens of the industry first in the app's menu and on its Home; it switches nothing off, and every operation works the same in every industry. Omit or null to keep it; audited with the other changes."
          },
          "posting_approval_limit": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,16}|(?=[\\d.]{1,17}0*$)\\d*\\.\\d*0*$)"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Approval Limit",
            "description": "The posting approval limit in the functional currency: whatever a person posts (a manual journal, a bill, an invoice, a payment, a refund, a VAT settlement, a revaluation, a depreciation run) whose functional amount is above it waits for a second person, and so does its reversal. A new company starts at about CHF 100,000 in its currency as a round figure (100000.00 CHF, EUR, USD, GBP or CAD, 1000000.00 SEK, 15000000 JPY). Omit it to keep the limit; null removes it (a one-person company). Only a person with the admin scope changes it (403 `posting_limit_admin_only`). A lower limit applies at once; raising or removing it waits for a second person (policy action `change_posting_limit`): the answer keeps the old limit and names the request in `posting_limit_request` (409 `posting_limit_change_waiting` while one waits, until it is decided or its requester withdraws it with `POST /v1/approvals/{approval_id}/withdraw`). A person alone in the organization (one active person, nobody else disabled or demoted in the last 30 days) changes it at once. Audited as `entity.posting_limit` with the value before and after (and `alone` when it applied so)."
          }
        },
        "type": "object",
        "title": "EntityUpdate",
        "description": "Fields that can change after an entity was created (null leaves a field as is, but the\nposting approval limit, which null removes).",
        "examples": [
          {
            "building_number": "5",
            "street": "Seestrasse",
            "town": "Zurich"
          }
        ]
      },
      "EntryInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code or id."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "The posting date, ISO 8601 (e.g. `2026-09-30`); it decides the fiscal period, which must be open."
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "title": "Description",
            "description": "What the entry is for; shown in the journal and the general ledger. At least one character."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/LineInput"
            },
            "type": "array",
            "minItems": 2,
            "title": "Lines",
            "description": "The lines of the entry, at least two. Debits and credits must balance."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Where the entry comes from. Over the API it is always `manual`: omit it. Subledger entries are created by their own endpoints.",
            "default": "manual"
          },
          "source_ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Ref",
            "description": "Your own reference for the entry, e.g. a document number in another system; free text, null when omitted."
          },
          "provenance": {
            "additionalProperties": true,
            "type": "object",
            "title": "Provenance",
            "description": "Free-form JSON that records where the entry came from. Over the API it must be empty: omit it."
          },
          "auto_reverse_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auto Reverse On",
            "description": "Reverse the entry on this date (e.g. the first day of the next period for an accrual). The reversal is posted when the entry is posted, also after an approval; the date must be after entry_date, in an open period."
          },
          "confirm_rate": {
            "type": "boolean",
            "title": "Confirm Rate",
            "description": "Use the `fx_rate` typed on a line even when it differs by more than 10% from the reference rate (ECB) of the entry date. Without it such a line is refused (422 `fx_rate_implausible`); with it the line's `fx` records the confirmation and the reference rate.",
            "default": false
          },
          "adjustment_period": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 15.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Adjustment Period",
            "description": "Post into this adjustment period (e.g. 13) instead of the regular period; entry_date must be the last day of the fiscal year."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "entry_date",
          "description",
          "lines"
        ],
        "title": "EntryInput",
        "examples": [
          {
            "description": "Accrued audit fee September 2026",
            "entity": "CH01",
            "entry_date": "2026-09-30",
            "lines": [
              {
                "account": "6500",
                "debit": "1500.00",
                "description": "Audit fee"
              },
              {
                "account": "2300",
                "credit": "1500.00",
                "description": "Accrual"
              }
            ]
          }
        ]
      },
      "EntryRef": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "The journal entry."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number once posted."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft` (a dividend the shareholder has not accepted yet), `pending_approval`, `posted` or `rejected`."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "entry_id",
          "number",
          "status"
        ],
        "title": "EntryRef"
      },
      "ErrorBody": {
        "type": "object",
        "title": "ErrorBody",
        "description": "What went wrong. Some errors carry more fields, e.g. `field` or `header`.",
        "required": [
          "code",
          "message"
        ],
        "additionalProperties": true,
        "properties": {
          "code": {
            "type": "string",
            "description": "Machine-readable: `unauthorized`, `forbidden`, `missing_right` (`scope`, `credential`: `key` or `session`; the right the caller lacks), `four_eyes` (`action`; `nobody_else`: true when no other person may approve yet, so one is invited), `policy_denied`, `approver_declaration_missing`, `approver_same_person` and `approver_acknowledgement_needed` (ADR-0098), `review_wait` (`release_at`: the AI reviewer holds the step until then), `passkey_step_up` (`within_minutes`: touch your passkey again, `POST /v1/auth/step-up`), `passkey_required`, `passkey_refused` (`reason`), `passkey_expired`, `passkey_none`, `passkey_elsewhere` (made at an address the site no longer uses), `passkey_exists`, `passkey_last`, `passkey_reset_yourself` and `passkey_reset_elsewhere` (`email`) (ADR-0101), `not_found`, `conflict`, `integrity_violation`, `precondition_failed`, `suspended` (the organization is read-only), `framework_unverified` and `framework_not_implemented` (`framework`: no group run under it), `validation_failed`, `invalid`, `agents_unavailable`, `agent_failed`, `model_busy` and `model_unavailable` (no language model answered in time: try again in a minute), `refdata_error`, `mail_failed`, `rate_limited`, `not_issued`, `store_unavailable`, `export_in_progress`, `export_not_ready`, `no_signed_link`, `exports_unavailable`, `party_not_active` (with `party`, `party_id`, `party_name`, `party_kind` and `party_status`), `party_blocked` and `party_inactive` (the same details), `period_closed` (`period`; a document also `document_date`; an e-invoice imported with `submit` also `einvoice`: true), `fx_rate_missing` (`base`, `quote`, `date`: no exchange rate for the day or month yet), `entry_not_draft` and `document_not_draft` (`status`), `draft_not_editable` (`status`), `draft_from_process` (`source`), `too_many_decimals` (`amount`, `currency`), `fiscal_year_missing` (`year`, `entity`), `audit_file_country` (`format`, `country`), `siren_missing` (`entity`), `audit_period_range` (`from_period`, `to_period`), `audit_periods_open` (`periods`), `file_too_large` (`max_mb`), `allocations_do_not_add_up` (`amount`, `allocated`), `not_a_bank_account` (`account`), `document_not_settleable` and `document_allocated_twice` (`document`), `document_amount_differs` (`document`, `amount`, `document_amount`), `more_than_open` (`document`, `amount`, `open_amount`), `receipt_in_future` (`date`, `today`), `credit_other_party`, `credit_not_posted` (`status`), `credit_more_than_invoiced` (`total`, `document`, `left`), `credit_settlement_waiting` (`document`), `more_than_left_to_apply` (`source`, `amount`, `left`), `nothing_to_apply` (`source`), `application_before_document` (`date`, `earliest`), `application_before_settlement` (`date`, `latest`), `product_inactive` (`product`), `product_unpriced` (`product`, `currency`, `date`), `document_date_required`, `recurring_line_incomplete` (`line`), `negative_total` (`total`), `discount_more_than_line` (`line`, `discount`, `amount`), `discount_more_than_document` (`discount`, `amount`), `discount_negative_line` (`line`), `credit_line_unknown` (`document`, `line`), `credit_discount_required` (`document`, `line`, `discount`), `vendor_invoice_twice` (`external_number`, `document`), `vendor_invoice_twice_supplier` (`external_number`, `document`, `party`, `party_name`), `vat_recovery_not_applicable`, `order_status` (`document`, `status`), `not_an_expense_account` (`account`), `before_order_date` (`order_date`), `order_in_use` (`document`), `received_more_than_ordered` (`line`, `received`, `ordered`), `received_beyond_closed` (`line`, `received`, `ordered`, `closed`), `order_nothing_to_close` (`document`), `bill_without_order`, `bill_not_blocked`, `variance_reason_missing`, `statement_currency_differs` (`statement_currency`, `account`, `currency`), `statement_imported` (`statement`), `bank_line_done` (`status`), `ignore_reason_missing`, `bank_line_payment_not_booked` (`payment`), `bank_line_amount_differs` (`payment`, `amount`, `booked`, `currency`), `bank_line_parties_differ`, `bank_line_to_itself`, `control_account` (`account`), `no_period_for_date` (`date`), `no_adjustment_period` (`period`, `date`), `manual_line_tags` (`line`), `account_inactive` (`account`), `control_account_manual` (`account`, `name`), `control_account_on_document`, `contra_account_on_document`, `tax_account_on_document` and `document_account_type` (`account`, `name`, `use`: `sales`, `purchase` or `acquisition`; the last also `type`), `nothing_to_book`, `due_before_document` (`date`, `document_date`), `credit_before_document` and `payment_before_document` (`date`, `document`, `document_date`), `payment_in_future` and `receipt_date_in_future` (`date`, `today`), `account_currency_only` (`account`, `currency`), `entry_does_not_balance` (`debit`, `credit`), `entry_off_in_currency` (`currency`, `difference`, `limit`: the largest FX rounding difference booked), `fx_rate_implausible` (`line`, `currency`, `rate`, `reference`, `date`, `tolerance`: a typed rate too far from the reference rate; confirm it to use it anyway), `reversal_before_entry` and `reversal_not_after_entry` (`date`, `entry_date`), `entry_not_posted` and `approval_decided` (`status`), `entry_already_reversed` and `reversal_waits` (`entry`), `entry_not_pending`, `posting_limit_admin_only`, `posting_limit_invalid`, `posting_limit_change_waiting` (`approval_id`), `posting_limit_changed`, `approval_policy_change_waiting` (`approval_id`), `approval_policy_changed`, `approval_policy_admin_only`, `approval_withdraw_own_only`, `approval_withdraw_admin_only`, `approval_not_withdrawable`, `payment_already_reversed`, `payment_entry_not_reversible`, `payment_not_posted`, `payment_reversal_stale` and `payment_matched_to_bank_line` (`payment`), `payment_on_account_applied` (`payment`, `applications`), `payment_on_account_refunded` (`payment`), `refund_not_on_account` (`payment`), `bank_line_not_matched` (`status`), `bank_line_bare`, `bank_line_not_returnable` and `bank_line_return_undo` (`payment`), `status_report_not_xml`, `status_report_wrong_format`, `status_report_unknown_file` (`file`), `status_report_unknown_payment` (`payment`, `file`), `reversal_reason_missing`, `reversal_reason_too_long` (`max`), `asset_accounts_pair`, `asset_accounts_differ` (`cost_account`, `accumulated_account`), `asset_cost_account_contra` (`cost_account`), `asset_accumulated_account_cost` (`accumulated_account`), `asset_accumulated_account_not_contra` (`accumulated_account`, `choices`), `asset_exists` and `asset_code_ambiguous` (`asset`), `source_not_a_bill`, `credit_account_missing`, `depreciation_after_year` (`asset`, `year`), `asset_status` and `acquisition_not_posted` (`asset`, `status`), `disposal_waits`, `acquisition_waits` and `depreciation_waits` (`asset`), `proceeds_account_missing` (`proceeds`), `asset_change_waits` (`asset`, `kind`, `date`), `sale_invoice_not_posted` (`status`), `sale_invoice_waits`, `asset_change_before_service` (`asset`, `in_service`), `asset_change_in_future` (`date`, `today`), `depreciation_booked_later` (`asset`, `entry`), `asset_changed_later` (`asset`, `date`), `asset_life_over` (`asset`), `retirement_too_large` (`asset`, `cost`), `no_impairment` and `impairment_too_large` (`asset`, `carrying`), `revaluation_not_allowed` and `revaluation_not_built` (`law`), `revaluation_no_change` (`asset`, `carrying`), `impairment_reversal_not_allowed` (`law`), `no_impairment_to_reverse` (`asset`), `no_reversal` (`asset`, `carrying`), `impairment_reversal_too_large` (`asset`, `most`), `proceeds_account_not_cash` (`account`), `depreciation_ran` (`period`), `salvage_not_below_cost` (`salvage`, `cost`), `in_service_before_acquisition` (`in_service_date`, `acquisition_date`), `disposal_before_in_service` (`asset`, `disposal_date`, `in_service_date`), `disposal_in_future` (`asset`, `disposal_date`, `today`), `acquisition_reversal_waits` (`asset`), `asset_depreciated` (`asset`, `entry`), `asset_value_changed` (`asset`, `kind`, `date`), `depreciation_earlier_period` (`period`, `earlier`), `period_not_started` (`period`, `start`, `today`), `period_already_closed` and `close_on_record` (`period`), `period_not_ready` (`period`, `failing`), `not_a_person`, `working_day_range` (`step`, `day`), `no_periods_yet` (`entity`), `unknown_close_check` (`check`), `task_retired`, `task_decided_by_check`, `task_inactive`, `task_already_done` and `task_not_done` (`task`), `account_name_invalid`, `account_number_invalid`, `account_exists` (`account`), `fiscal_year_exists` (`year`, `entity`), `fiscal_year_overlaps` (`year`, `period`), `fiscal_year_gap` (`year`, `missing`, `entity`), `reopen_reason_missing`, `vat_period_invalid` (`period`), `vat_period_months`, `vat_form_missing`, `recap_form_missing` and `annual_form_missing` (`country`, `date`), `vat_period_italy` and `vat_period_uk` (`period`), `vat_period_country` (`country`, `period`), `oss_eu_only`, `split_payment_italian_customers_only`, `vat_form_changed` (`start`, `end`, `form`), `box_not_adjustable` and `box_offset_missing` (`box`), `vat_return_blocks`, `vat_return_not_draft` and `vat_return_not_final` (`document`, `status`), `vat_period_locked` and `oss_period_locked` (`document`, `vat_return_id`, `start`, `end`), `net_rates_wrong_method`, `net_rates_missing`, `net_rate_unknown` (`series`), `net_rate_accounts`, `vat_method_swiss`, `tax_fx_unavailable`, `tax_fx_none`, `filing_extension_de`, `cash_basis_unavailable` and `registrations_canada` (`country`), `registration_unknown` (`provinces`), `provincial_period_unknown` (`provinces`), `quick_method_canada` (`country`), `quick_method_rate`, `quick_method_region` (`province`), `quick_method_wrong_method`, `vat_method_not_standard`, `vat_period_french` (`period`), `tax_fx_kept` (`date`, `basis`), `settlement_before_period_end` (`date`), `settlement_no_open_period`, `vat_ledger_changed` and `settlement_ledger_changed` (`document`), `vat_return_has_errors` (`document`, `count`), `vat_unexplained` (`amount`, `currency`), `tax_category_unknown` (`country`, `date`, `category`, `categories`: no rate in force applies to the line's tax category), `vat_filing_not_final` (`document`, `status`), `vat_return_submitted` (`document`, `date`), `vat_submitted_in_future` (`date`, `today`), `vat_submitted_before_period_end` (`date`, `end`), `vat_return_not_submitted`, `vat_return_paid` and `vat_nothing_to_pay` (`document`), `vat_filing_reason_missing`, `vat_payment_other_company` and `vat_payment_is_settlement` (`entry`), `vat_payment_not_posted` (`entry`, `status`), `vat_payment_before_settlement` (`entry`, `date`, `settlement_date`), `vat_payment_wrong_side` (`entry`, `account`, `side`), `vat_payment_linked` (`entry`, `document`), `sales_tax_not_us` (`entity`), `sales_tax_state_unknown`, `sales_tax_state_rate_unknown` (`state`, `date`), `sales_tax_registered` (`state`), `sales_tax_registration_dates`, `sales_tax_code_taken`, `sales_tax_area_member` (`jurisdiction`, `state`), `sales_tax_area_other_state` (`area`, `customer`), `sales_tax_exemption_incomplete`, `sales_tax_exemption_dates` (`start`, `end`), `sales_tax_exemption_states` (`states`), `sales_tax_frequency_filed` (`state`), `sales_tax_credit_line_missing`, `sales_tax_use_tax_charged`, `sales_tax_use_tax_sales`, `sales_tax_use_tax_not_registered` (`entity`, `state`), `sales_tax_return_approved`, `sales_tax_return_not_approved`, `sales_tax_customer_state_missing` (`customer`, `customer_id`), `sales_tax_rate_missing` (`jurisdiction`, `date`), `sales_tax_period_frequency` (`frequency`, `period`), `sales_tax_return_filed` (`state`, `period`, `date`), `sales_tax_filed_in_future` (`date`, `today`), `sales_tax_filed_before_period_end` (`date`, `end`), `sales_tax_reason_missing`, `sales_tax_return_withdrawn`, `sales_tax_return_paid`, `sales_tax_payment_entry` and `sales_tax_payment_linked` (`entry`), `sales_tax_payment_in_period` (`entry`, `date`), `sales_tax_payment_wrong_side` (`entry`, `account`), `year_not_closed`, `year_close_not_pending` and `year_close_not_closed` (`year`, `status`), `year_locked` and `year_changed` (`fiscal_year`), `before_catch_up` (`catch_up`), `destination_account_missing`, `destination_account_type` and `destination_account_unusable` (`account`), `no_swiss_withholding_tax` (`entity`), `notification_swiss_only` (`shareholder`, `country`), `loss_destination`, `result_account_destination`, `nothing_to_appropriate`, `catch_up_year_closed` and `year_appropriated` (`year`), `reversal_not_reversed`, `appropriation_reversed`, `group_dividend_not_reversed`, `year_reopened`, `nothing_to_carry_forward`, `nothing_to_catch_up` (`date`), `year_close_cancelled`, `year_close_blocked`, `catch_up_period_not_open` (`period`), `role_missing`, `appropriation_exceeds_remainder` (`remainder`), `chart_unknown` and `chart_lacks_roles` (`chart`), `entity_currency_needed` (`country`), `entity_exists` and `chart_template_unknown` (`entity`), `account_name_iban`, `account_codes_in_use` (`codes`, `roles`), `fiscal_year_length` (`year`), `period_reopen_refused` (`period`), `product_ssp_missing` (`product`, `currency`, `date`), `product_ssp_over_time` (`product`, `period`), `service_period_outside` (`line`, `start`, `end`), `obligation_ssp_missing`, `ssp_too_small` and `obligation_incomplete` (`line`), `price_decimals` (`currency`), `contract_not_draft`, `contract_not_active`, `not_awaiting_approval`, `not_cancellable`, `subscription_not_draft` and `subscription_not_active` (`document`, `status`), `customer_not_active` (`party`, `status`), `terms_changed`, `obligation_over_time`, `obligation_done` (`line`, `status`), `satisfied_in_future` (`date`), `before_contract_start` (`date`, `start`), `adjustment_period_no_revenue`, `presentation_role_missing` (`entity`, `role`, `contract`), `presentation_reversal_no_period` (`date`), `recognition_period_not_open` (`period`, `status`), `recognition_pending`, `recognition_earlier_period` (`period`), `recurring_name_missing`, `field_not_clearable` (`field`), `end_before_start` (`start`, `end`), `recurring_ended`, `recurring_schedule_fixed`, `recurring_pause_refused`, `recurring_run_refused`, `recurring_not_activatable` and `recurring_not_pending` (`status`), `recurring_no_next_due`, `recurring_journal_ended`, `recurring_journal_schedule_fixed`, `recurring_journal_human_only`, `recurring_journal_not_activatable`, `recurring_journal_pause_refused` and `recurring_journal_run_refused` (all three `status`), `billing_through_future` (`through`, `today`), `subscription_no_contract` (`document`), `billing_period_misaligned` (`document`, `date`), `opportunity_not_found` (`entity`), `opportunity_not_won` (`opportunity`, `party`), `subscription_line_not_recurring`, `subscription_line_goods` and `price_period_unsupported` (`line`, `product`), `subscription_ssp_missing` and `list_price_missing` (`line`, `product`, `currency`, `date`), `subscription_currency_unpriced` (`line`, `product`, `currency`, `date`, `priced`: the currencies it has a price in, joined such as `CHF, EUR`), `subscription_bills_nothing`, `renewal_automatic`, `renewal_approved` and `renewal_not_approved` (`document`), `subscription_start_closed` (`date`, `period`, `status`), `subscription_ending` (`document`, `date`), `subscription_invoices_unposted` (`document`, `count`), `subscription_credit_not_posted` (`document`, `status`), `amendment_pending` and `subscription_end_bills_nothing` (`document`), `end_outside_term` (`date`, `start`, `end`), `end_date_missing`, `change_incomplete`, `change_outside_term` (`document`, `date`, `start`, `end`), `change_changes_nothing` and `change_bills_nothing` (`document`), `subscription_changing` (`document`, `date`), `contract_recognised_after_end` (`document`, `date`), `contract_recognition_gap`, `contract_recognised_more` and `contract_nothing_left` (`document`), `contract_promise_open` (`document`, `line`), `contract_worth_nothing`, `contract_active_not_cancelled`, `contract_change_pending`, `contract_change_nothing`, `contract_credit_not_possible` and `contract_end_not_earlier` (`document`; the last also `end`), `contract_change_outside_term` (`document`, `date`, `start`, `end`), `contract_change_recognised` (`document`, `date`, `first`), `contract_of_subscription` (`document`, `subscription`), `contract_documents_unposted` (`document`, `count`), `contract_credit_not_posted` (`document`, `status`), `ic_dividend_to_itself`, `ic_no_relationship` (`entity`, `partner`), `ic_party_code_taken` (`entity`, `party`), `ic_loan_same_entity`, `ic_loan_reference_exists` (`reference`), `ic_loan_relationship_inactive`, `ic_link_not_retryable`, `ic_link_not_drafted`, `ic_mirror_not_draft`, `ic_relationship_not_suspendable` and `ic_relationship_not_suspended` (`status`), `ic_loan_not_active` (`loan`, `status`), `ic_loan_accrued_through` and `ic_interest_accrued_already` (`loan`, `date`), `ic_drawdown_date` and `ic_no_interest_due` (`start`, `end`), `ic_facility_exceeded`, `ic_repay_more_than_principal` and `ic_settle_more_than_open` (`loan`, `amount`, `currency`, `limit`), `ic_loan_missing`, `ic_no_interest_accrued` (`loan`), `ic_dividend_missing`, `ic_dividend_not_accepted` (`dividend`, `status`), `ic_vat_group_country` (`vat_group`, `country`), `ic_relationship_same_entity`, `ic_relationship_exists` (`entity`, `partner`, `status`), `ic_suspend_reason_missing`, `ic_refresh_alone`, `ic_relationship_pending`, `ic_status_alone`, `ic_request_waiting`, `ic_nothing_changes`, `ic_nothing_sent`, `ic_goods_not_supported` (`line`), `ic_terms_changed`, `ic_mirror_impossible`, `plan_name_taken` (`name`), `plan_year_no_periods` (`year`, `entity`), `copy_from_other_plan`, `plan_version_not_draft` and `plan_version_not_submitted` (`version`, `status`), `plan_line_twice` (`line`, `account`, `period`), `plan_account_unknown` (`line`, `account`), `plan_account_type` (`line`, `account`), `plan_period_unknown` (`line`, `period`), `plan_period_other_year` (`line`, `year`), `plan_version_empty`, `plan_version_older` (`version`, `current`), `version_changed` (`version`), `all_periods_closed`, `budget_does_not_roll`, `compare_same_version`, `compare_other_entity`, `product_line_not_sales`, `obligation_line_not_sales`, `document_number_ambiguous` (`document`), `obligation_other_contract` (`document`, `line`), `contract_not_billable` (`document`, `status`), `obligation_group_party`, `obligation_goods`, `obligation_account_fixed` and `contract_account_manual` (`account`), `credit_names_obligation` (`document`, `line`), `qr_iban_needs_reference`, `payment_reference_invalid` (`reference`), `qr_reference_needs_qr_iban`, `qr_iban_qr_only`, `activity_not_task`, `crm_task_done` (`task`), `opportunity_won_final`, `opportunity_final` and `opportunity_lost_reopen` (`document`), `opportunity_probability_closed`, `opportunity_forecast_closed` and `opportunity_stage_same` (`document`, `stage`), `quota_twice` (`month`), `prospect_name_needed`, `close_day_future` (`date`), `close_day_before_created` (`document`, `date`, `created`), `opportunity_prospect_only` (`document`, `prospect`), `contact_not_of_party` (`party`), `contact_erased`, `contact_erase_agent`, `contact_needs_customer`, `autopilot_pass_running`, `autopilot_needs_a_person`, `autopilot_question_closed`, `support_queue_exists` and `support_queue_inactive` (`queue`), `support_queue_unknown`, `support_address_taken` (`address`, `queue`), `support_case_closed`, `support_status_same` and `support_no_recipient` (`case`), `support_not_case_address` (`case`, `addresses`), `support_not_draft` (`case`), `support_status_agent`, `support_send_agent`, `support_contact_without_customer`, `support_inbox_unknown` (`addresses`), `support_assignee_invalid`, `party_parent_self`, `merge_agent`, `merge_needs_every_record`, `merge_same`, `party_merged`, `party_merge_has_records` (`party`, `records`), `party_merge_loop`, `contact_merge_other_party`, `lead_converted`, `lead_erased` and `lead_disqualified` (`document`), `lead_disqualified_reason`, `lead_erase_agent`, `email_invalid`, `lead_form_agent`, `lead_form_origin_invalid`, `lead_form_unknown`, `lead_form_suspended`, `lead_form_origin`, `lead_form_page_expired`, `lead_form_email`, `lead_form_name` and `lead_form_too_long` (`field`), `lead_customer`, `custom_fields_full` (`record`, `limit`), `custom_field_exists` and `custom_field_unknown` (`record`, `key`), `custom_field_not_choice`, `custom_field_choice_in_use` (`field`, `choices`), `custom_field_retired` (`field`), `custom_field_value` (`field`, `expected`), `user_not_in_org`, `owner_outside_view`, `vendor_no_owner`, `sales_team_exists` (`name`), `not_team_member`, `hand_over_needs_all_records`, `owner_disabled`, `user_exists` and `user_google_password` (`email`), `tester_needs_masked_copy`, `unknown_scopes` (`scopes`), `own_admin_scope`, `disable_yourself`, `access_until_missing`, `access_until_past`, `access_until_too_far`, `own_access_until`, `preferences_web_only`, `user_disabled_password`, `user_workspace_password` (`domain`), `tax_book_needs_class`, `asset_class_other_regime` (`asset_class`, `book`, `regime`), `asset_in_book` (`asset`, `book`), `deferred_tax_ran` and `depreciation_before_deferred_tax` (`period`), `deferred_tax_order` (`period`, `earlier`), `book_no_deferred_tax`, `book_no_deferred_tax_accounts`, `book_code_reserved`, `book_exists` and `deferred_tax_book_exists` (`book`), `no_deferred_tax_book` (`entity`), `deferred_tax_account_missing` (`entity`, `role`), `deferred_tax_needs_rate`, `group_date_month_end` (`date`), `goodwill_policy_not_allowed` (`framework`, `goodwill_policy`), `goodwill_years_not_used` (`framework`, `goodwill_policy`), `goodwill_years_too_long` (`framework`, `years`, `max_years`), `reporting_currency_parent` (`currency`, `entity`, `parent_currency`), `group_exists` (`group`), `parent_not_member`, `consolidated_before_acquired` (`date`, `acquired`), `ownership_decimals` (`places`), `acquisition_cost_pair`, `member_version_before` (`entity`, `date`, `in_force`), `member_version_waiting` (`entity`), `member_version_closed` (`entity`, `version`, `as_of`), `cash_discount_outside_vat`, `cash_discount_terms_pair`, `cash_discount_beyond_terms` (`days`, `terms`), `cash_discount_needs_days`, `cash_discount_after_due` (`date`, `due`), `execution_after_cash_discount` (`payment`, `document`, `cash_discount_date`, `execution_date`), `no_cash_discount_terms` (`document`), `cash_discount_period_ended` (`document`, `date`), `cash_discount_over_percent` (`document`, `amount`, `currency`, `percent`, `settled`, `limit`), `cash_discount_over_left` (`document`, `amount`, `currency`, `limit`), `qr_bill_sales_only`, `qr_bill_not_posted` (`status`), `qr_bill_currency` (`currency`), `qr_bill_settled` (`document`), `qr_bill_no_account` (`currency`), `execution_date_past`, `payment_listed_twice`, `payment_already_sent` (`document`), `payment_released_meanwhile`, `iban_invalid`, `bank_account_listed_twice`, `not_qr_iban` and `iban_registered_elsewhere` (`iban`), `party_already_active`, `party_bank_change_waiting`, `party_activation_waiting`, `party_details_change_waiting`, `group_party_details`, `party_status_change_waiting` and `party_has_open_items` (`party`, `open`), `party_status_unchanged` (`party`, `status`), `party_status_move` (`party`, `status`, `new_status`), `party_customer_and_vendor`, `customer_exists` and `vendor_exists` (`party`), `other_company` (404: `entity`, `party`, `kind`; a customer or vendor asked for by its id in a company it is not of), `no_vat_number`, `not_bank_account` and `bank_details_change_waiting` (`account`), `iban_is_qr_iban`, `invoice_not_posted_output` and `document_not_rejected` (`status`), `opening_balance_document` (`document`), `ic_mirror_void`, `product_needs_price_period` and `product_one_off_period` (`product`), `product_price_exists` (`product`, `currency`, `date`), `product_exists` (`product`, `entity`), `product_ssp_exists` (`product`, `currency`, `latest`), `price_list_exists` (`price_list`, `entity`), `price_list_price_exists` (`price_list`, `product`, `min_quantity`, `date`), `price_list_currency` (`price_list`, `currency`), `price_list_inactive` (`price_list`), `price_list_assigned_meanwhile` (`party`, `currency`), `customer_no_email` (`party`), `not_email_address` (`addresses`), `not_customer_address` (`party`, `addresses`), `handover_not_posted` (`status`), `handover_before_document` (`document`, `date`), `handover_in_future`, `handover_too_old` (`date`, `earliest`), `no_reminder_due` (`party`, `currency`), `reminder_not_due` (`count`), `reminder_currency_needed` (`party`, `currencies`), `reminder_covered_by_credits` (`party`, `currency`), `reminder_in_future` and `reminder_backdated` (`date`, `today`), `reminder_out_of_date` (`date`, `days`), `reminder_withdrawn`, `reminder_handed_over`, `reminder_settings_levels`, `dunning_block_not_invoice`, `dunning_block_exists` and `dunning_block_missing` (`document`), `sales_number_ambiguous` (`document`), `sales_status` (`document`, `status`), `order_valid_until`, `quote_valid_before_date` (`date`, `valid_until`), `sales_field_required` (`field`), `accepted_in_future`, `accepted_before_quote` (`document`, `date`), `quote_expired` (`document`, `valid_until`), `order_invoiced` (`document`), `opportunity_other_customer` (`opportunity`, `party`), `sales_document_deal_customer` (`document`), `credit_limit_exceeded` (`customer`, `owed`, `credit_limit`, `currency`), `credit_limit_customers_only`, `withholding_rate_without_code`, `withholding_vendors_only`, `withholding_rate_invalid`, `withholding_code_unknown` (`withholding_code`, `country`), `withholding_rate_mismatch` (`withholding_code`, `rate`), `order_nothing_left` and `invoice_before_order` (`document`; the last also `date`), `order_not_invoiced` (`document`), `order_line_invalid` (`line`), `order_line_over_invoiced` (`document`, `line`, `quantity`, `left`), `order_line_not_invoice`, `order_other_customer` (`document`), `order_not_invoiceable` (`document`, `status`), `period_reversed` (`start`, `end`), `copy_of_test_copy`, `test_copy_limit` (`count`), `test_copy_same_name`, `test_copy_removing`, `setup_in_test_copy`, `setup_done`, `company_in_test_copy`, `setup_not_done`, `currency_code_invalid` (`currency`), `currency_not_ecb` (`currency`), `functional_currency_not_ecb` (`currency`), `currency_missing`, `matrix_too_many_currencies` (`count`), `amount_too_large` (`count`), `same_currency_pair`, `history_too_long` (`count`), `opening_item_group_party` (`party`), `opening_item_after_opening` (`date`, `opening`), `opening_item_own_number` (`document`), `document_number_exists` (`document`), `vendor_document_booked` (`party`, `document`), `role_held_elsewhere` (`role`, `holder`, `account`), `control_role_postings` (`role`, `account`, `count`), `account_nothing_changes`, `account_role_deactivate` (`account`, `role`), `account_in_use` (`account`), `account_change_waiting` (`account`), `country_not_served` (`country`), `standard_not_offered` (`country`, `standard`), `books_currency_not_offered` (`country`, `currency`, `currencies`), `subdivision_missing`, `subdivision_not_asked` (`country`), `tax_period_not_offered` (`country`), `tax_number_not_asked` (`country`), `statement_iban_elsewhere` (`iban`, `account`), `statement_iban_differs` (`iban`, `account`, `registered`), `statement_iban_unknown` (`iban`), `iban_in_several_names` (`iban`, `accounts`), `proposal_discount_account` (`entity`), `not_vendor_bill` (`document`), `bill_listed_twice` (`document`), `no_bank_account_in_currency` (`currency`), `key_for_person_or_agent`, `agent_key_scopes`, `org_name_missing`, `file_damaged`, `file_empty`, `file_type_unsupported`, `file_already_attached`, `vendor_unreadable`, `bill_already_recorded` (`party`, `invoice`), `bill_file_type`, `file_not_its_type` (`kind`), `file_already_captured`, `einvoice_no_issue_date`, `einvoice_unreadable`, `einvoice_seller_unknown`, `not_sales_document`, `zugferd_german_only`, `xrechnung_german_only` (`entity`), `fx_next_year_missing`, `fx_revaluation_done` (`period`), `fx_revaluation_pending` (`period`), `write_off_not_invoice` (`document`), `write_off_nothing_open` (`document`), `write_off_in_future` (`date`, `today`), `write_off_before_settlement` (`date`, `earliest`), `write_off_keep_cash_basis` (`entity`), `write_off_not_posted` (`document`, `status`), `write_off_follow_up_waiting` (`write_off`), `recovery_more_than_written_off` (`amount`, `left`, `currency`), `write_off_vat_corrected` (`write_off`), `write_off_all_recovered` (`write_off`), `follow_up_in_future` (`date`, `today`), `follow_up_before_write_off` (`date`, `earliest`), `allowance_done` (`period`), `allowance_buckets`, `doubtful_not_invoice` (`document`), `fx_regular_period_only`, `sample_data_test_only`, `sample_data_period_closed` (`date`, `entity`), `statement_already_imported`, `bank_line_not_ignored` (`status`), `statement_in_future` (`date`), `reconciliation_done` (`account`, `date`, `by`), `reconciliation_reset_already` (`account`, `date`), `reconciliation_later` (`account`, `date`, `later`), `bank_posting_before_line` (`date`, `booking_date`), `reconciliation_in_future` (`date`), `statement_balance_missing` (`account`, `date`), `statement_balance_differs` (`statement`, `balance`, `currency`), `reconciliation_unexplained` (`amount`, `currency`), `bill_not_matchable` (`status`), `variance_not_pending`, `receipt_line_invalid` (`line`), `order_number_ambiguous` (`document`), `task_field_required`, `report_line_unknown` (`line`), `report_line_type` (`line`, `line_type`, `account_type`), `role_unknown` (`role`), `role_account_type` (`role`, `account_type`), `party_field_required`, `party_subdivision_mismatch` (`subdivision`, `country`, `postal_code`), `party_currency_without_rates` (`currency`, `functional`), `party_own_bank_account` (`iban`, `kind`), `refresh_schedule_unknown`, `platform_key_scopes`, `platform_key_name`, `platform_key_days`, `model_named_twice`, `user_already_member` (`email`, `status`), `template_needs_country` (`entity`), `granularity_unknown`, `range_too_long` (`count`), `compare_unknown`, `breakdown_unknown`, `metric_unknown` (`metric`), `split_unknown`, `metric_not_splittable`, `account_filter_needs_entity`, `import_needs_date`, `import_has_problems` (`count`), `mapping_invalid`, `deletion_too_late`, `subscription_invoice_locked` (`period`, `subscription`), `line_amount_too_large` (`amount`), `rate_not_positive` (`rate`), `role_account_missing` (`entity`, `role`), `already_in_org`, `connector_unknown_app`, `connector_redirect_not_allowed` (`address`), `connector_request_invalid`, `connector_needs_session`, `role_or_scopes`, `vat_number_invalid` (`field`, `value`, `country`, `example`), `idempotency_key_reused`, `csv_mapping_invalid`, `manual_entries_only`, `test_copy_no_email`, `test_copy_no_einvoice`, `test_copy_no_qr_bill`, `test_copy_no_payment_file`, `xls_not_supported`, `file_not_table`, `csv_unreadable`, `xlsx_invalid`, `workbook_too_large`, `workbook_no_sheet`, `table_empty`, `too_many_columns` (`count`), `column_unnamed` (`column`), `column_twice` (`columns`), `row_too_many_values` (`line`, `count`), `too_many_rows` (`count`), `statement_date_unreadable` (`value`), `lease_exists` (`lease`), `lease_term_frequency` (`term`, `months`), `lease_not_short_term` (`term`), `lease_account_type` (`account`, `role`, `account_type`), `lease_accounts_differ` (`account`), `lease_account_currency` (`account`, `currency`), `lease_not_draft` and `lease_not_active` (`lease`, `status`), `lease_credit_account_missing`, `lease_change_date`, `lease_change_booked`, `lease_end_date`, `lease_end_unbooked` and `lease_end_booked_after` (`lease`, `date`), `lease_change_later` (`lease`), `lease_change_nothing`, `lease_change_too_large` (`amount`, `currency`), `lease_nothing_due` (`period`), `lease_regular_period_only`, `lease_change_pending` (`lease`), `lease_local_framework` and `lease_operating_ifrs` (`entity`), `statement_amount_unreadable` (`value`), `statement_amount_range` (`value`), `statement_entry_no_date`, `statement_not_xml` (`format`), `statement_wrong_format` (`format`), `statement_no_report` (`format`), `csv_line_unreadable` (`line`: an amount that cannot be read), `csv_line_date_invalid` (`line`, `value`, `format`: a day that does not exist, or one written otherwise), `csv_line_no_currency` (`line`), `csv_no_transactions`, `csv_column_missing` (`column`), `dimension_unknown` (`line`, `dimension`), `dimension_value_unknown` (`line`, `dimension`, `value`, `date`), `dimension_required` (`line`, `account`, `dimension`), `dimension_exists` (`dimension`), `dimension_limit` (`max`), `dimension_value_exists` (`dimension`, `value`), `mt940_balance_unreadable` (`value`), `mt940_line_unreadable` (`line`), `mt940_balance_mismatch` (`statement`), `tax_category_needed` (`country`, `date`, `choices`: several rates or kinds of exemption of the rate type match; the line's `tax_category` chooses one), `tax_rate_type_missing` (`rate_type`, `country`, `date`). Lists of what stops an action (a payment's `problems`, a vendor's `payment_blockers`) carry the same codes and details: `party_no_iban` (`party`), `iban_invalid` (`iban`), `iban_not_group_account` and `iban_not_confirmed` (`iban`, `party`), `party_not_activated`, `party_blocked`, `party_inactive`, `party_block_waiting` and `party_bank_change_waiting` (`party`), `bill_payment_blocked` (`bill`, `order`), `bills_different_accounts`, `bills_other_currency` (`currency`, `bill_currency`), `bills_several_references`, `qr_iban_needs_reference`, `payment_account_no_iban` (`account`), `debit_account_not_swiss`, `payment_not_outgoing`, `payment_already_executed`, `payment_recorded_paid` (recorded as already executed by the bank), `payment_reversed`, `payment_waiting_approval`, `payment_not_approved` (`status`), `payment_no_number`, `payment_reference_invalid` (`reference`), `payment_currency_swiss` (`currency`), `qr_reference_needs_qr_iban`, `payment_amount_too_large` (`amount`), `payment_cross_border` (`currency`, `country`); releasing such a payment is refused with the first of them. `group_opening_run_missing` (`as_of`: the group cash flow needs the run at that date). SEPA direct debits (ADR-0076): `creditor_id_invalid` (`creditor_id`), `mandate_iban_not_sepa` (`iban`), `mandate_reference_invalid` and `mandate_reference_taken` (`reference`), `mandate_signed_future`, `mandate_not_changeable` (`mandate`, `status`), `mandate_not_active` (`mandate`); what stops a collection (a proposal's skipped invoices, a collection's problems, a refusal): `mandate_pending_approval`, `mandate_rejected`, `mandate_revoked`, `mandate_expired`, `mandate_used` and `mandate_change_waiting` (`mandate`), `mandate_returned` and `mandate_refused` (`mandate`, `reason`), `direct_debit_no_mandate`, `direct_debit_prenotification` (`notified`, `days`, `earliest`), `direct_debit_before_due_date` (`due`), `direct_debit_no_transit_account` (`role`), `direct_debit_discount_account` (`role`, `due`), `direct_debit_discount_not_taken` (`discount`, `due`), `direct_debit_discount_period_ended` (`document`, `date`), `direct_debit_account_changed` (`mandate`), `direct_debit_no_creditor_id`, `direct_debit_account_not_eur` (`account`), `direct_debit_not_eur_invoice` (`document`), `direct_debit_debtor_address` (`party`), `invoice_listed_twice`, `not_a_direct_debit` (`document`). Stock: `no_warehouse` (`entity`), `warehouse_exists` (`warehouse`, `entity`), `warehouse_inactive`, `warehouse_is_default` and `warehouse_holds_stock` (`warehouse`), `not_a_stock_item`, `stock_item_exists`, `stock_item_not_goods` and `stock_item_in_stock` (`product`), `not_an_inventory_account` (`account`), `entity_needed`, `not_enough_stock` (`item`, `warehouse`, `on_hand`, `wanted`, `unit`, `date`), `unit_cost_needed`, `revaluation_without_stock` and `stock_value_short` (`item`), `stock_changed` (`document`, `item`), `stock_date_future` (`date`, `today`), `nothing_to_post`, `transfer_same_warehouse` (`warehouse`), `count_in_future` (`date`, `today`), `count_open_exists` (`warehouse`, `document`), `nothing_to_count`, `count_item_unknown` (`item`, `document`), `count_not_open` (`document`, `status`), `count_waits` (`document`), `count_not_counted` (`document`, `count`), `count_moved_since` (`document`, `date`), `count_pending_postings` (`document`, `posting`), `count_revalued_since` (`item`, `date`), `stock_backdated` (`item`, `date`), `stock_counted_since` (`document`, `date`), `agent_zero_value`. Delivery notes: `delivery_note_unknown`, `delivery_note_not_draft` (`document`, `status`), `delivery_order_line_mismatch` (`document`, `line`), `delivery_order_line_over_shipped` (`document`, `line`, `quantity`, `left`), `delivery_order_line_on_draft_note` (`document`, `line`, `quantity`, `left`, `reserved`: a draft note reserves the rest), `delivery_order_line_shipped_on_notes` (the same and `notes`: posted notes shipped the rest, invoice their lines), `delivery_note_not_printable` (`status`), `delivery_note_not_invoiceable` (`document`, `status`), `delivery_nothing_left` (`document`), `delivery_no_price` (`product`, `currency`), `invoice_before_delivery` (`document`, `date`), `delivery_line_not_invoice`, `delivery_line_unknown`, `delivery_line_other_product` (`document`, `line`), `delivery_line_over_invoiced` (`document`, `line`, `quantity`, `left`), `goods_returned_not_stock`, `goods_returned_needs_line`, `goods_returned_other_line` (`document`, `line`), `goods_returned_beyond_shipped` (`document`, `line`, `quantity`, `left`), `goods_returned_no_cost` (`document`, `line`), `warehouse_not_needed`, `order_not_shippable` (`document`, `status`), `order_delivered` (`document`), `stock_shipment_held` (`document`), `stock_not_kept` (a line names stock where no module keeps it). Capacity: `not_a_capacity_item`, `capacity_item_exists` and `capacity_item_not_service` (`product`), `capacity_full` (`product`, `date`, `free`, `wanted`), `capacity_booked` (`product`, `date`, `booked`), `booking_cancelled` (`document`), `days_reversed`, `days_span_too_long`, `booking_held` (`document`, `held_by`: a module keeps it, such as a hotel stay's rooms), `booking_not_held`. Hospitality: `not_a_room_type` (`product`), `room_rate_overlaps` (`product`, `season`, `first_night`, `last_night`), `room_no_price` (`product`, `currency`, `date`), `room_too_many_guests` (`product`, `most`), `stay_days`, `stay_status` (`document`, `status`), `stay_not_arrived` (`document`, `date`), `stay_departure` (`document`, `arrival`, `latest`), `stay_invoiced` (`document`). Linked mailboxes: `mailbox_person_only`, `mailbox_needs_draft`, `mailbox_test_copy`, `mailbox_not_available`, `mailbox_nothing_allowed`, `mailbox_not_linked`, `mailbox_not_readable`, `google_link_refused`, `google_unavailable`. HubSpot: `hubspot_not_available`, `hubspot_oauth_not_available`, `hubspot_test_copy`, `hubspot_other_account`, `hubspot_token_refused`, `hubspot_state_invalid`, `hubspot_refused`, `hubspot_unavailable`, `hubspot_not_readable`. Recurring revenue: `month_in_future` (`month`, `today`). Quotes online: `agent_records_no_answer`, `agent_hands_over_nothing`, `link_of_quote_only`, `quote_being_revised`, `quote_not_open_online` (`document`, `state`, `revision`), `signer_email_invalid`. Notifications and webhooks: `notifications_person_only`, `webhook_person_only`, `webhook_url_refused` (`reason`), `webhook_limit` (`limit`), `webhook_endpoint_disabled`. Goods received: `stock_item_line_goods` (`line`, `item`), `return_before_receipt_posted` (`line`, `quantity`, `posted`), `return_while_write_off_waits` (the same), `return_after_write_off` (the same and `written_off`), `return_beyond_received` (the same and `received`), `grni_nothing_open`, `grni_line_nothing_open` (`line`), `grni_write_off_pending` (`order`), `grni_write_off_future` (`date`, `today`), `grni_write_off_before_receipt` (`line`, `date`, `received`), `grni_write_off_control_account` (`account`), `grni_write_off_account_missing` (`line`). Branding: `brand_colour` (not a colour like #1d4ed8), `brand_colour_contrast` and `brand_accent_contrast` (too light to read on white), `brand_logo_empty`, `brand_logo_too_large`, `brand_logo_svg`, `brand_logo_invalid`, `brand_no_logo`. Saved reports: `saved_report_invalid` (a field, filter or grouping its source does not have), `saved_report_day` (not a day), `saved_report_not_found`, `saved_report_not_yours` (only its owner changes it), `saved_report_no_person` (a key the system issued keeps none), `saved_report_limit`, `saved_report_recipient_not_shared`, `saved_report_sent_recently`. Rolling forecast: `no_rolling_forecast` (not made yet; the next scheduled run makes it). Roles: `area_closed` (`area`: the caller's role does not open that area of the app), `unknown_area` (`areas`), `role_not_found` (`role`), `role_title_taken` (`title`), `role_template` (`role`: no ready-made role), `role_ready_made` (`role`: a ready-made role is not changed or removed), `role_in_use` (`role`, `people`), `roles_person_only` (for a person signed in, not a key), `suggestion_gone` (`suggestion`). Expenses: `expense_not_found`, `expense_not_yours` (`expense`), `expense_not_draft` and `expense_not_held` (`expense`, `status`), `expense_incomplete` (`expense`, `field`), `expense_total_needed`, `expense_account_unknown` (`account`), `expense_card_needed`, `expense_vat_rate` (`rate`, `country`), `receipt_already_claimed` (`expense`, `expense_id`), `receipt_is_einvoice`, `not_a_receipt` (`document`), `person_not_found` (`person`), `card_exists` and `card_not_yours` (`card`), `card_not_found`, `card_line_not_found`, `card_line_matched`, `card_line_refund`, `statement_column_missing` (`column`), `statement_date` and `statement_amount` (`line`). A precise code keeps the HTTP status of its kind (a closed period is a 409 like `conflict`). Company sign-in: `company_sign_in_unavailable` (not offered on this server), `company_sign_in_issuer` (`field`: not an Okta domain, an Entra tenant or an https issuer), `company_sign_in_domain` (`field`, `domain`), `company_sign_in_unreachable` (the provider did not answer for the issuer), `company_sign_in_untried` (sign in through it once before making it the only way in), `company_sign_in_not_found`, `company_sign_in_none` (no organization of the address signs in with a company account), `company_sign_in_several` (use the organization's own link), `company_sign_in_state` (too old, or not started here), `company_sign_in_refused` (the ID token does not hold), `company_sign_in_email` (no verified address of a covered domain). Shopify: `shopify_not_available`, `shopify_test_copy`, `shopify_other_shop`, `shopify_app_refused`, `shopify_consent_not_available`, `shopify_state_invalid`, `shopify_refused`, `shopify_unavailable`, `shopify_not_readable`, `shopify_order_too_long` (`order`), `shopify_order_unmade`, `shopify_invoice_differs` (`document`), `shopify_cost_missing` (`products`), `shopify_payout_unexplained` (`payout`), `shopify_refund_unmatched`, `shopify_refund_not_invoiced` and `shopify_refund_invoices` (`order`), `shopify_refund_differs` (`document`). Addresses: `address_not_found` (no suggestions on this server, or Google does not give the address chosen: type it in), `rate_limited` (`retry_after_seconds`: the organization's addresses of the day are used up).",
            "examples": [
              "validation_failed"
            ]
          },
          "message": {
            "type": "string",
            "description": "A sentence for a person; do not parse it.",
            "examples": [
              "entry does not balance"
            ]
          },
          "hint": {
            "type": "string",
            "description": "For an agent: the API call that resolves the refusal, e.g. `POST /v1/entities/CH01/parties/V-ACME/activate?kind=vendor`. Absent when there is none."
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "title": "ErrorEnvelope",
        "description": "The body of every error the ERP raises on purpose.",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ErrorBody"
          }
        }
      },
      "EventTypeOut": {
        "properties": {
          "type": {
            "type": "string",
            "title": "Type",
            "description": "The event's name, e.g. `deal.won`."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "When it is sent and what its `data` holds."
          }
        },
        "type": "object",
        "required": [
          "type",
          "description"
        ],
        "title": "EventTypeOut"
      },
      "Evidence": {
        "properties": {
          "field": {
            "type": "string",
            "title": "Field",
            "description": "Which extracted field this supports, e.g. 'invoice_number'."
          },
          "quote": {
            "type": "string",
            "title": "Quote",
            "description": "Verbatim text from the document."
          }
        },
        "type": "object",
        "required": [
          "field",
          "quote"
        ],
        "title": "Evidence"
      },
      "ExchangeDifferenceItem": {
        "properties": {
          "contract": {
            "type": "string",
            "title": "Contract",
            "description": "Number of the revenue contract."
          },
          "contract_id": {
            "type": "string",
            "format": "uuid",
            "title": "Contract Id",
            "description": "Id of the revenue contract."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The contract's currency."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The realised exchange difference posted, in the functional currency: positive a gain, negative a loss. A contract in a foreign currency carries its position at historical rates; billing what was recognised before it was billed (or crediting what was billed in advance) at another rate leaves this difference on the contract liability, which the run moves to the exchange gain or loss account."
          }
        },
        "type": "object",
        "required": [
          "contract",
          "contract_id",
          "currency",
          "amount"
        ],
        "title": "ExchangeDifferenceItem"
      },
      "ExecutionDate": {
        "properties": {
          "payment": {
            "type": "string",
            "title": "Payment",
            "description": "Payment number."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the payment."
          },
          "requested": {
            "type": "string",
            "format": "date",
            "title": "Requested",
            "description": "The date asked for."
          },
          "execution_date": {
            "type": "string",
            "format": "date",
            "title": "Execution Date",
            "description": "The business day the payment is sent for."
          },
          "adjusted": {
            "type": "boolean",
            "title": "Adjusted",
            "description": "`true` when the requested date was moved to a business day."
          },
          "calendars": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Calendars",
            "description": "Clearing calendars used, e.g. `ch.six.sic`."
          },
          "convention": {
            "type": "string",
            "title": "Convention",
            "description": "Business day convention applied (`following`)."
          },
          "dataset_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dataset Version",
            "description": "Version of the calendar data."
          }
        },
        "type": "object",
        "required": [
          "payment",
          "currency",
          "requested",
          "execution_date",
          "adjusted",
          "calendars",
          "convention"
        ],
        "title": "ExecutionDate",
        "description": "A payment's requested execution date and the business day it is sent for."
      },
      "ExpenseCheck": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The check: `receipt`, `readable`, `duplicate`, `age`, ..."
          },
          "result": {
            "type": "string",
            "enum": [
              "pass",
              "warn"
            ],
            "title": "Result",
            "description": "`warn` holds it for a person."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "What the check found, in words."
          }
        },
        "type": "object",
        "required": [
          "name",
          "result",
          "detail"
        ],
        "title": "ExpenseCheck"
      },
      "ExpenseInput": {
        "properties": {
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code (or id) of the company it is for, e.g. `CH01`; default: the organization's only company, else the one the person's last expense was for."
          },
          "card_line": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Card Line",
            "description": "The company card payment it is (`GET /v1/expense-card-lines`): its day, amount and merchant are taken from it."
          },
          "merchant": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Merchant",
            "description": "Who was paid."
          },
          "receipt_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receipt Date",
            "description": "When; default today."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217; default the company's."
          },
          "total": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "What was paid, VAT included; needed without a card line."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What it was for, and why there is no receipt."
          }
        },
        "type": "object",
        "title": "ExpenseInput",
        "description": "An expense without a receipt file: a card payment whose receipt is lost, or one typed.",
        "examples": [
          {
            "card_line": "3b0c8f4e-6a52-4f8e-9c1c-1f0d7a2b9e10",
            "description": "Lost"
          },
          {
            "description": "Train Zürich - Bern, ticket in the app",
            "entity": "CH01",
            "merchant": "SBB",
            "receipt_date": "2026-10-20",
            "total": "68.00"
          }
        ]
      },
      "ExpenseOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the expense."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "`EX-2026-000001`, gap-free per company and year."
          },
          "person": {
            "type": "string",
            "title": "Person",
            "description": "Who paid (`user:<id>`)."
          },
          "person_name": {
            "type": "string",
            "title": "Person Name",
            "description": "Their name."
          },
          "status": {
            "type": "string",
            "enum": [
              "approved",
              "draft",
              "held",
              "posted",
              "rejected",
              "withdrawn"
            ],
            "title": "Status",
            "description": "`draft` (read, to check and submit), `held` (the AI reviewer or the controls wait for a person), `approved` (not booked yet: see `problem`), `posted`, `rejected` or `withdrawn`."
          },
          "source": {
            "type": "string",
            "enum": [
              "demo",
              "no_receipt",
              "receipt"
            ],
            "title": "Source",
            "description": "`receipt` (read from a file), `no_receipt` (a card payment or ticket without a receipt file) or `demo`."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The receipt's file (`GET /v1/documents`)."
          },
          "merchant": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Merchant",
            "description": "Who was paid."
          },
          "merchant_country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Merchant Country",
            "description": "ISO 3166 country of the merchant."
          },
          "receipt_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receipt Date",
            "description": "The receipt's date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The receipt's currency."
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Paid, VAT included, in the receipt's currency."
          },
          "vat_lines": {
            "items": {
              "$ref": "#/components/schemas/VatLine-Output"
            },
            "type": "array",
            "title": "Vat Lines",
            "description": "The VAT printed per rate."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "The category: the expense account's code."
          },
          "account_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Name",
            "description": "The account's name."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "The project and other dimensions."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What it was for."
          },
          "paid_with": {
            "type": "string",
            "enum": [
              "card",
              "own"
            ],
            "title": "Paid With",
            "description": "`own` or `card`."
          },
          "card": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Card",
            "description": "The card's last four digits, when paid by card."
          },
          "card_line_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Card Line Id",
            "description": "The card payment it is matched to."
          },
          "confidence": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Confidence",
            "description": "0 to 1: how sure the reading is."
          },
          "filled": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Filled",
            "description": "How each field was filled: `read` (from the receipt), `history` (as your last ones), `default`, `card` (from the card line) or `person`."
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/ExpenseCheck"
            },
            "type": "array",
            "title": "Checks",
            "description": "What the AI reviewer checked, once submitted."
          },
          "review": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Review",
            "description": "The reviewer's reasoning in words."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request, once submitted."
          },
          "bill_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bill Id",
            "description": "The bill it is booked as, once posted."
          },
          "bill_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bill Number",
            "description": "That bill's number."
          },
          "paid_back": {
            "type": "boolean",
            "title": "Paid Back",
            "description": "Paid back to the person (or, by card, settled by the card): nothing open."
          },
          "problem": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Problem",
            "description": "Why an approved expense is not booked yet."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the receipt came in (UTC)."
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At",
            "description": "When it was submitted."
          },
          "decided_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided By",
            "description": "Who approved or rejected it."
          },
          "decided_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided At",
            "description": "When."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "person",
          "person_name",
          "status",
          "source",
          "document_id",
          "merchant",
          "merchant_country",
          "receipt_date",
          "currency",
          "total",
          "vat_lines",
          "account",
          "account_name",
          "dimensions",
          "description",
          "paid_with",
          "card",
          "card_line_id",
          "confidence",
          "filled",
          "checks",
          "review",
          "approval_id",
          "bill_id",
          "bill_number",
          "paid_back",
          "problem",
          "created_at",
          "submitted_at",
          "decided_by",
          "decided_at"
        ],
        "title": "ExpenseOut"
      },
      "ExpenseUpdate": {
        "properties": {
          "merchant": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Merchant",
            "description": "Who was paid."
          },
          "merchant_country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Merchant Country",
            "description": "ISO 3166 country of the merchant."
          },
          "receipt_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receipt Date",
            "description": "The receipt's date."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217."
          },
          "total": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Paid, VAT included."
          },
          "vat_lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/VatLine-Input"
                },
                "type": "array",
                "maxItems": 10
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Lines",
            "description": "The VAT printed per rate."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "The category: code of the expense account it is booked to."
          },
          "dimensions": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dimensions",
            "description": "The project and other dimensions, `{dimension code: value code}`; an empty value takes one away."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What it was for."
          },
          "paid_with": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "card",
                  "own"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Paid With",
            "description": "`own` (paid back to you) or `card` (your company card)."
          },
          "card": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Card",
            "description": "Which of your company cards, when you hold several."
          }
        },
        "type": "object",
        "title": "ExpenseUpdate",
        "description": "What the person changes on a draft before submitting it (all optional).",
        "examples": [
          {
            "account": "6640",
            "dimensions": {
              "project": "P-LYON"
            }
          }
        ]
      },
      "ExportInfo": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the payment export."
          },
          "message_id": {
            "type": "string",
            "title": "Message Id",
            "description": "Message id of the pain.001 file."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was released (UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "The actor that released it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "message_id",
          "created_at",
          "created_by"
        ],
        "title": "ExportInfo"
      },
      "ExportInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity whose payments are released, e.g. `CH01`."
          },
          "payments": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "maxItems": 5000,
            "minItems": 1,
            "title": "Payments",
            "description": "Ids of the outgoing payments to release (`GET /v1/payments`): status `posted`, not yet sent, 1 to 5000, each listed once."
          },
          "execution_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Execution Date",
            "description": "Day the bank is to pay; default: payment date or today. Moved to the next business day of the payment's clearing calendars (CHF: SIC; EUR: TARGET and SIC) when it is not one. A payment that takes a cash discount is refused (`execution_after_cash_discount`) when that day is after the discount period."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "payments"
        ],
        "title": "ExportInput",
        "examples": [
          {
            "entity": "CH01",
            "execution_date": "2026-10-05",
            "payments": [
              "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            ]
          }
        ]
      },
      "ExportLink": {
        "properties": {
          "url": {
            "type": "string",
            "title": "Url",
            "description": "A link that downloads the package without credentials until `expires_at`: treat it like a password."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "title": "Expires At",
            "description": "When the link stops working (UTC)."
          },
          "file_name": {
            "type": "string",
            "title": "File Name",
            "description": "Name of the ZIP file."
          },
          "size_bytes": {
            "type": "integer",
            "title": "Size Bytes",
            "description": "Size of the ZIP file in bytes."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the ZIP file; compare it after the download."
          }
        },
        "type": "object",
        "required": [
          "url",
          "expires_at",
          "file_name",
          "size_bytes",
          "sha256"
        ],
        "title": "ExportLink"
      },
      "ExportOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the export."
          },
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "The organization the export is of."
          },
          "status": {
            "type": "string",
            "enum": [
              "expired",
              "failed",
              "queued",
              "running",
              "succeeded"
            ],
            "title": "Status",
            "description": "`queued` (waiting for the export job), `running`, `succeeded` (the package can be downloaded until `expires_at`), `failed` (see `error`), or `expired` (it succeeded, but the download period has ended and the package is deleted; ask for another)."
          },
          "via": {
            "type": "string",
            "enum": [
              "platform",
              "tenant"
            ],
            "title": "Via",
            "description": "Who asked: `tenant` (an administrator of the organization) or `platform` (the operator, for example at the end of the contract)."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of the package's README."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why the export was made; null if not said."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who asked, as an actor object (`type`, `id`, `name`)."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "title": "Requested At",
            "description": "When it was asked for (UTC)."
          },
          "started_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Started At",
            "description": "When the export job took it; null while queued."
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At",
            "description": "When it succeeded or failed; null before."
          },
          "stage": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Stage",
            "description": "What the job is doing now: `tables`, `documents`, `reports`, `integrity` or `finish`; null before it starts."
          },
          "progress": {
            "additionalProperties": true,
            "type": "object",
            "title": "Progress",
            "description": "How far each stage is (counts of tables, files and reports done)."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why it failed, in a sentence without internals; null otherwise."
          },
          "cutoff": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cutoff",
            "description": "The moment of the database snapshot the package was made from: everything posted before it is in the package, nothing after."
          },
          "file_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "File Name",
            "description": "Name of the ZIP file; null until it succeeded."
          },
          "size_bytes": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Size Bytes",
            "description": "Size of the ZIP file in bytes."
          },
          "sha256": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sha256",
            "description": "SHA-256 of the ZIP file as 64 hexadecimal characters. It is also recorded in the platform's append-only audit record, so that we can later attest that this is what we handed over. Compare it with the hash of the file you downloaded."
          },
          "manifest_sha256": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Manifest Sha256",
            "description": "SHA-256 of `manifest.sha256` inside the package, which lists the hash of every other file."
          },
          "file_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "File Count",
            "description": "Number of files in the package."
          },
          "row_count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Row Count",
            "description": "Number of table rows in the package."
          },
          "complete": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Complete",
            "description": "True when every table has all its rows and every stored file was read, checked against its SHA-256 and included; false when some file could not be (they are listed in `integrity/document-problems.csv` in the package)."
          },
          "statement": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Statement",
            "description": "The hand-over statement: the organization, the package's hashes, sizes and counts, the hash-chain result per entity, and the id of the record in the platform's audit table. Keep it with the archive."
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At",
            "description": "Until when the package can be downloaded; null until it succeeded."
          }
        },
        "type": "object",
        "required": [
          "id",
          "org_id",
          "status",
          "via",
          "language",
          "note",
          "requested_by",
          "requested_at",
          "started_at",
          "finished_at",
          "stage",
          "progress",
          "error",
          "cutoff",
          "file_name",
          "size_bytes",
          "sha256",
          "manifest_sha256",
          "file_count",
          "row_count",
          "complete",
          "statement",
          "expires_at"
        ],
        "title": "ExportOut",
        "description": "An export: the request, how far it is, and what was handed over once it has succeeded."
      },
      "ExportRequest": {
        "properties": {
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "sv"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "The language of the package's README: `en`, `de`, `fr`, `it` or `sv`. Default: the language of the person who asks, else the country of the organization's first entity (`de` for CH and DE, `fr` for FR, `it` for IT, `sv` for SE), else `en`."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why the export is made, up to 500 characters; kept with the request and in the audit trail."
          }
        },
        "type": "object",
        "title": "ExportRequest",
        "examples": [
          {
            "language": "de",
            "note": "Archive copy at contract end"
          }
        ]
      },
      "ExtraInput": {
        "properties": {
          "product": {
            "type": "string",
            "title": "Product",
            "description": "Code (or id) of an active product: breakfast, minibar."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Quantity",
            "description": "Quantity; default 1.",
            "default": "1"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price",
            "description": "Net unit price; omitted: the customer's or list price."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text; omitted: its name."
          }
        },
        "type": "object",
        "required": [
          "product"
        ],
        "title": "ExtraInput"
      },
      "ExtractedBill": {
        "properties": {
          "is_invoice": {
            "type": "boolean",
            "title": "Is Invoice",
            "description": "False if the file is not a vendor invoice."
          },
          "vendor_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Name",
            "description": "Vendor name as printed."
          },
          "vendor_vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Vat Number",
            "description": "Vendor VAT number as printed."
          },
          "vendor_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Iban",
            "description": "Vendor IBAN as printed."
          },
          "vendor_country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Country",
            "description": "ISO 3166 alpha-2 code."
          },
          "vendor_street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Street",
            "description": "Vendor street and building number as printed."
          },
          "vendor_postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Postal Code",
            "description": "Vendor postal code as printed."
          },
          "vendor_town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Town",
            "description": "Vendor town as printed."
          },
          "invoice_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Number",
            "description": "The vendor's invoice number."
          },
          "order_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Reference",
            "description": "Our purchase order number as quoted on the invoice (PO, order no., Bestellnummer, BT-13), copied exactly; null if none."
          },
          "invoice_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoice Date",
            "description": "Invoice date (ISO 8601)."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "Due date (ISO 8601), if printed."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ExtractedLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The invoice lines the model read."
          },
          "net_total": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net Total",
            "description": "Net total as printed, a number."
          },
          "vat_total": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Total",
            "description": "VAT total as printed, a number."
          },
          "gross_total": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Gross Total",
            "description": "Gross total as printed, a number."
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "description": "0 to 1: how sure you are of the extraction overall."
          },
          "evidence": {
            "items": {
              "$ref": "#/components/schemas/Evidence"
            },
            "type": "array",
            "title": "Evidence",
            "description": "Quotes from the document that support fields of the extraction."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Anything a reviewer should know."
          }
        },
        "type": "object",
        "required": [
          "is_invoice",
          "confidence"
        ],
        "title": "ExtractedBill"
      },
      "ExtractedLine": {
        "properties": {
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Line text as printed."
          },
          "quantity": {
            "type": "number",
            "title": "Quantity",
            "description": "Quantity, a number.",
            "default": 1
          },
          "unit_price": {
            "type": "number",
            "title": "Unit Price",
            "description": "Net unit price, excluding VAT."
          },
          "vat_rate_percent": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Rate Percent",
            "description": "VAT rate printed, e.g. 8.1"
          },
          "vat_amount": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Amount",
            "description": "VAT printed for this line."
          },
          "supply_type": {
            "type": "string",
            "enum": [
              "electronic_services",
              "goods",
              "services"
            ],
            "title": "Supply Type",
            "description": "`goods`, `services` or `electronic_services`.",
            "default": "services"
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Suggested account code from the chart provided."
          },
          "account_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Reason",
            "description": "Why that account; null if none."
          }
        },
        "type": "object",
        "required": [
          "description",
          "unit_price"
        ],
        "title": "ExtractedLine"
      },
      "FeedOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Id of the feed."
          },
          "kind": {
            "type": "string",
            "enum": [
              "ingest",
              "legislation"
            ],
            "title": "Kind",
            "description": "`ingest` (data fetched on a schedule) or `legislation` (watched for changes)."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the feed provides."
          },
          "latest": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Latest",
            "description": "Newest date covered by the stored data (ISO 8601); null if none."
          },
          "age_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Age Days",
            "description": "How many days old the newest data is; null if none."
          },
          "state": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "error",
                  "no_data",
                  "ok",
                  "stale",
                  "unknown"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "State",
            "description": "`ok`, `stale` (older than its freshness rule allows), `no_data`, `error` or `unknown`."
          },
          "detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Detail",
            "description": "A sentence explaining the state; null if none."
          },
          "freshness": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Freshness",
            "description": "The freshness rule of the feed, in words; null if none."
          },
          "max_age_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Age Days",
            "description": "How old the newest data may be before it is `stale`; null if no limit."
          },
          "min_horizon_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Min Horizon Days",
            "description": "How far ahead the data must reach; null if no requirement."
          },
          "last_run": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/IngestRunOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The most recent ingest run of the feed; null if none."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "description"
        ],
        "title": "FeedOut"
      },
      "FieldMapping": {
        "properties": {
          "field": {
            "type": "string",
            "title": "Field",
            "description": "Our field, e.g. `name` or `country`."
          },
          "column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Column",
            "description": "The file's column it is read from (as the header names it, compared without case, spaces and hyphens); null when the file has none and the field is left empty."
          },
          "required": {
            "type": "boolean",
            "title": "Required",
            "description": "True when a row cannot be imported without it."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the field is, and the Salesforce field it is."
          },
          "label": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Label",
            "description": "The name of a field of the organization's own (`custom.<key>`); null for the import's fields."
          }
        },
        "type": "object",
        "required": [
          "field",
          "column",
          "required",
          "description"
        ],
        "title": "FieldMapping",
        "description": "Which column of the file one of our fields is read from."
      },
      "FieldSuggestion": {
        "properties": {
          "field": {
            "type": "string",
            "title": "Field",
            "description": "The field's key, one of the request's."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "The value proposed, as the field takes it."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why, in one sentence."
          }
        },
        "type": "object",
        "required": [
          "field",
          "value",
          "reason"
        ],
        "title": "FieldSuggestion"
      },
      "Figure": {
        "properties": {
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "In the report's currency: each currency's sum converted at the report's fixing (currencies in `unconverted` left out)."
          },
          "by_currency": {
            "items": {
              "$ref": "#/components/schemas/CurrencyAmount"
            },
            "type": "array",
            "title": "By Currency",
            "description": "The sums in the deals' own currencies, as recorded."
          }
        },
        "type": "object",
        "required": [
          "amount",
          "by_currency"
        ],
        "title": "Figure"
      },
      "FileOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the stored file."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "File name, e.g. `INV-2026-000001.pdf`."
          },
          "content_type": {
            "type": "string",
            "title": "Content Type",
            "description": "Media type, determined from the bytes."
          },
          "size": {
            "type": "integer",
            "title": "Size",
            "description": "Size in bytes."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the file, hex; the download carries it too."
          },
          "source": {
            "type": "string",
            "enum": [
              "archived_output",
              "attached",
              "captured",
              "received"
            ],
            "title": "Source",
            "description": "Where the file comes from: `received` (the e-invoice a vendor sent, booked from its data), `captured` (the PDF or image bill capture read), `archived_output` (an invoice or credit note exactly as issued: what the customer got) or `attached` (an original added afterwards)."
          },
          "variant": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Variant",
            "description": "Of an archived output: which output it is (`pdf-auto-qr`, `zugferd-en16931-auto`, `xrechnung`); null for the other files."
          },
          "stored_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Stored By",
            "description": "The actor (`type`, `id`, `name`) that stored it."
          },
          "stored_at": {
            "type": "string",
            "format": "date-time",
            "title": "Stored At",
            "description": "When it was stored (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "filename",
          "content_type",
          "size",
          "sha256",
          "source",
          "variant",
          "stored_by",
          "stored_at"
        ],
        "title": "FileOut",
        "description": "A file stored for a document; the bytes are `GET /v1/documents/{id}/files/{file_id}`."
      },
      "FiscalCalendar": {
        "properties": {
          "calendar": {
            "type": "string",
            "enum": [
              "13x4",
              "4-4-5",
              "4-5-4",
              "5-4-4",
              "monthly"
            ],
            "title": "Calendar",
            "description": "`monthly` (default; twelve calendar months), `4-4-5`, `4-5-4` or `5-4-4` (52/53 weeks in quarters of those period lengths), or `13x4` (thirteen periods of four weeks).",
            "default": "monthly"
          },
          "year_end": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "last_weekday",
                  "month_end",
                  "nearest_weekday"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Year End",
            "description": "month_end for monthly calendars; last_weekday (default) or nearest_weekday for week-based ones."
          },
          "end_weekday": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "friday",
                  "monday",
                  "saturday",
                  "sunday",
                  "thursday",
                  "tuesday",
                  "wednesday"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "End Weekday",
            "description": "The weekday a week-based year ends on (default saturday)."
          },
          "adjustment_periods": {
            "type": "integer",
            "maximum": 2.0,
            "minimum": 0.0,
            "title": "Adjustment Periods",
            "description": "One-day closing periods on the last day of the year.",
            "default": 0
          }
        },
        "type": "object",
        "title": "FiscalCalendar",
        "description": "How to divide a fiscal year into periods.",
        "examples": [
          {
            "adjustment_periods": 1,
            "calendar": "4-4-5"
          }
        ]
      },
      "FiscalYearOut": {
        "properties": {
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year, the calendar year in which it ends."
          },
          "calendar": {
            "type": "string",
            "title": "Calendar",
            "description": "`monthly`, `4-4-5`, `4-5-4`, `5-4-4` or `13x4`."
          },
          "year_end": {
            "type": "string",
            "title": "Year End",
            "description": "`month_end`, `last_weekday` or `nearest_weekday`."
          },
          "end_weekday": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Weekday",
            "description": "The weekday a week-based year ends on; null on a monthly calendar."
          },
          "weeks": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Weeks",
            "description": "Number of weeks (52 or 53) of a week-based year; null on a monthly calendar."
          },
          "adjustment_periods": {
            "type": "integer",
            "title": "Adjustment Periods",
            "description": "Number of one-day adjustment periods on the last day (0 to 2)."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "First day of the year (ISO 8601)."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "Last day of the year (ISO 8601)."
          },
          "periods": {
            "items": {
              "$ref": "#/components/schemas/PeriodOut"
            },
            "type": "array",
            "title": "Periods",
            "description": "The periods of the year: regular ones, then adjustment periods."
          },
          "close": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/YearCloseSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "The year-end close of the year (the one holding it, else the newest): status, result, what is appropriated and what is left, and whether the general meeting is overdue; null when the year was never proposed for closing."
          }
        },
        "type": "object",
        "required": [
          "fiscal_year",
          "calendar",
          "year_end",
          "end_weekday",
          "weeks",
          "adjustment_periods",
          "start_date",
          "end_date",
          "periods"
        ],
        "title": "FiscalYearOut"
      },
      "FiscalYearRequest": {
        "properties": {
          "fiscal_year": {
            "type": "integer",
            "maximum": 2100.0,
            "minimum": 2000.0,
            "title": "Fiscal Year",
            "description": "The fiscal year to open, 2000 to 2100, e.g. 2027. It is the calendar year in which the year ends."
          },
          "calendar": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FiscalCalendar"
              },
              {
                "type": "null"
              }
            ],
            "description": "How to divide the year into periods. Default: the calendar of the previous year opened with one, else twelve calendar months."
          }
        },
        "type": "object",
        "required": [
          "fiscal_year"
        ],
        "title": "FiscalYearRequest",
        "examples": [
          {
            "calendar": {
              "adjustment_periods": 1,
              "calendar": "4-4-5"
            },
            "fiscal_year": 2027
          }
        ]
      },
      "Flux": {
        "properties": {
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period analysed, `<year>-<number>`, e.g. `2026-09`."
          },
          "comparison": {
            "type": "string",
            "title": "Comparison",
            "description": "The previous regular period it is compared with, or `none (first period)`."
          },
          "materiality": {
            "type": "string",
            "title": "Materiality",
            "description": "The threshold used, functional currency."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/FluxRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "One row per account, flagged rows first, then by size of the variance."
          }
        },
        "type": "object",
        "required": [
          "period",
          "comparison",
          "materiality",
          "rows"
        ],
        "title": "Flux"
      },
      "FluxInsight": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "`asset`, `liability`, `equity`, `revenue` or `expense`."
          },
          "current": {
            "type": "string",
            "title": "Current",
            "description": "Profit-and-loss accounts: the range's movement; others: the balance at the range's end. Functional currency, the account's normal direction."
          },
          "comparison": {
            "type": "string",
            "title": "Comparison",
            "description": "The same measure for the comparison range."
          },
          "variance": {
            "type": "string",
            "title": "Variance",
            "description": "`current` less `comparison`."
          },
          "variance_pct": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Variance Pct",
            "description": "The variance as a percentage of the comparison, one decimal; null when the comparison is zero."
          },
          "change": {
            "type": "string",
            "enum": [
              "cleared",
              "decrease",
              "increase",
              "new"
            ],
            "title": "Change",
            "description": "`new`: nothing in the comparison; `cleared`: nothing now."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "One plain sentence in English built from the numbers by a fixed template (no language model)."
          }
        },
        "type": "object",
        "required": [
          "account",
          "name",
          "type",
          "current",
          "comparison",
          "variance",
          "variance_pct",
          "change",
          "summary"
        ],
        "title": "FluxInsight"
      },
      "FluxRow": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "`asset`, `liability`, `equity`, `revenue` or `expense`."
          },
          "current": {
            "type": "string",
            "title": "Current",
            "description": "Profit-and-loss accounts: the period's movement; others: the balance at the period's end. Functional currency, account's normal direction."
          },
          "comparison": {
            "type": "string",
            "title": "Comparison",
            "description": "The same measure for the comparison period."
          },
          "variance": {
            "type": "string",
            "title": "Variance",
            "description": "`current` minus `comparison`."
          },
          "variance_pct": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Variance Pct",
            "description": "The variance as a percentage of the comparison, one decimal; null when the comparison is zero."
          },
          "flagged": {
            "type": "boolean",
            "title": "Flagged",
            "description": "True when the variance reaches the materiality and, if there is a comparison, 10% of it."
          }
        },
        "type": "object",
        "required": [
          "account",
          "name",
          "type",
          "current",
          "comparison",
          "variance",
          "variance_pct",
          "flagged"
        ],
        "title": "FluxRow"
      },
      "FollowUpOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the follow-up."
          },
          "write_off_id": {
            "type": "string",
            "format": "uuid",
            "title": "Write Off Id",
            "description": "The write-off it follows."
          },
          "kind": {
            "type": "string",
            "enum": [
              "recovery",
              "vat_correction"
            ],
            "title": "Kind",
            "description": "`recovery` (money received after the write-off) or `vat_correction` (the VAT of a write-off that kept it, corrected once the loss is final)."
          },
          "follow_up_date": {
            "type": "string",
            "format": "date",
            "title": "Follow Up Date",
            "description": "The day of its entry."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the invoice and the amounts."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "`recovery`: what was received; `vat_correction`: the amount, VAT included, whose VAT is corrected (what is written off less what was received before)."
          },
          "tax_amount": {
            "type": "string",
            "title": "Tax Amount",
            "description": "`recovery`: the output VAT owed again on what was received; `vat_correction`: the output VAT corrected."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "`recovery`: code of the bank account."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Free text."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_approval",
              "posted",
              "rejected"
            ],
            "title": "Status",
            "description": "`pending_approval` (decided on Approvals), `posted` or `rejected`."
          },
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "Its journal entry."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was asked for (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "write_off_id",
          "kind",
          "follow_up_date",
          "currency",
          "amount",
          "tax_amount",
          "bank_account",
          "note",
          "status",
          "journal_entry_id",
          "created_at"
        ],
        "title": "FollowUpOut",
        "description": "Money received after a write-off, or the VAT of a kept write-off corrected later."
      },
      "FollowUpResult": {
        "properties": {
          "follow_up": {
            "$ref": "#/components/schemas/FollowUpOut",
            "description": "The recovery or the VAT correction."
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "How its entry was submitted under the approval policy: `posted`, or `pending_approval` with the `approval_id` a second person decides."
          }
        },
        "type": "object",
        "required": [
          "follow_up",
          "submit"
        ],
        "title": "FollowUpResult"
      },
      "ForecastChange": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "amount",
              "came_into_view",
              "moved",
              "new",
              "settled"
            ],
            "title": "Kind",
            "description": "`settled` (expected before, gone now: paid, collected or cancelled), `new` (not expected before), `moved` (expected in another week now), `amount` (another amount now), `came_into_view` (in the week the horizon moved on to)."
          },
          "source": {
            "type": "string",
            "enum": [
              "payable",
              "payment",
              "receivable",
              "recurring_invoice",
              "recurring_journal",
              "subscription"
            ],
            "title": "Source",
            "description": "Where it comes from: `receivable` (an open customer invoice or credit note), `payable` (an open vendor bill or credit note), `payment` (a payment recorded but not posted yet: one waiting for approval, a payment run's), `recurring_invoice` and `subscription` (an invoice they will make), `recurring_journal` (an entry it will post on a cash account)."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "The document's number, the template's name."
          },
          "party_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Name",
            "description": "The customer's or vendor's name."
          },
          "before_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Before Date",
            "description": "When it was expected before."
          },
          "after_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "After Date",
            "description": "When it is expected now."
          },
          "before": {
            "type": "string",
            "title": "Before",
            "description": "What was expected before, in the company's currency."
          },
          "after": {
            "type": "string",
            "title": "After",
            "description": "What is expected now, in the company's currency."
          },
          "link": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Link",
            "description": "The app page of the document or template, if any."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "source",
          "reference",
          "party_name",
          "before_date",
          "after_date",
          "before",
          "after",
          "link"
        ],
        "title": "ForecastChange"
      },
      "ForecastChanges": {
        "properties": {
          "since": {
            "type": "string",
            "format": "date",
            "title": "Since",
            "description": "The day the earlier forecast was kept."
          },
          "opening_before": {
            "type": "string",
            "title": "Opening Before",
            "description": "The cash on that day."
          },
          "opening_after": {
            "type": "string",
            "title": "Opening After",
            "description": "The cash today."
          },
          "lowest_before": {
            "$ref": "#/components/schemas/LowestPoint",
            "description": "The lowest point the earlier one showed."
          },
          "totals": {
            "additionalProperties": {
              "type": "string"
            },
            "propertyNames": {
              "enum": [
                "amount",
                "came_into_view",
                "moved",
                "new",
                "settled"
              ]
            },
            "type": "object",
            "title": "Totals",
            "description": "The change each kind made to the cash over the weeks both forecasts cover."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/ForecastChange"
            },
            "type": "array",
            "title": "Items",
            "description": "The changes, largest first (at most 25)."
          },
          "more": {
            "type": "integer",
            "title": "More",
            "description": "How many smaller changes are not listed."
          }
        },
        "type": "object",
        "required": [
          "since",
          "opening_before",
          "opening_after",
          "lowest_before",
          "totals",
          "items",
          "more"
        ],
        "title": "ForecastChanges"
      },
      "ForecastLine": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "Stable from one week to the next: what it is and its record."
          },
          "source": {
            "type": "string",
            "enum": [
              "payable",
              "payment",
              "receivable",
              "recurring_invoice",
              "recurring_journal",
              "subscription"
            ],
            "title": "Source",
            "description": "Where it comes from: `receivable` (an open customer invoice or credit note), `payable` (an open vendor bill or credit note), `payment` (a payment recorded but not posted yet: one waiting for approval, a payment run's), `recurring_invoice` and `subscription` (an invoice they will make), `recurring_journal` (an entry it will post on a cash account)."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "The document's number, the template's name."
          },
          "party_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Code",
            "description": "The customer's or vendor's code."
          },
          "party_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Name",
            "description": "The customer's or vendor's name."
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "The day the cash is expected (today at the earliest)."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "The day it falls due, where it has one."
          },
          "week": {
            "type": "integer",
            "title": "Week",
            "description": "The week it falls in, 1 (this week) to 13."
          },
          "basis": {
            "type": "string",
            "enum": [
              "company_habit",
              "customer_habit",
              "dated",
              "due_date",
              "vendor_habit"
            ],
            "title": "Basis",
            "description": "How its day was found: `customer_habit` or `vendor_habit` (the due date moved by how late this customer paid, or this vendor was paid, over the last 12 months), `company_habit` (the same for all of the company's customers or vendors, for a party without payments yet), `due_date` (no payments to learn from) or `dated` (a payment's date, an entry's)."
          },
          "habit_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Habit Days",
            "description": "Days after the due date this party pays or is paid on average (negative: before); null where the day is a date."
          },
          "overdue": {
            "type": "boolean",
            "title": "Overdue",
            "description": "Its expected day has passed: counted in this week."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency it moves in."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "In `currency`, signed: positive comes in."
          },
          "functional": {
            "type": "string",
            "title": "Functional",
            "description": "In the company's currency, signed."
          },
          "link": {
            "type": "string",
            "title": "Link",
            "description": "Where the app shows it."
          },
          "posted": {
            "type": "boolean",
            "title": "Posted",
            "description": "Whether it is a posted document; false for a draft or a document or payment waiting for approval, and for what is scheduled."
          }
        },
        "type": "object",
        "required": [
          "key",
          "source",
          "reference",
          "party_code",
          "party_name",
          "date",
          "due_date",
          "week",
          "basis",
          "habit_days",
          "overdue",
          "currency",
          "amount",
          "functional",
          "link",
          "posted"
        ],
        "title": "ForecastLine"
      },
      "ForecastMonth": {
        "properties": {
          "month": {
            "type": "string",
            "title": "Month",
            "description": "`YYYY-MM`."
          },
          "quota": {
            "type": "string",
            "title": "Quota",
            "description": "Everyone's quota."
          },
          "closed": {
            "type": "string",
            "title": "Closed",
            "description": "Won in the month."
          },
          "commit": {
            "type": "string",
            "title": "Commit",
            "description": "Commit expected in the month."
          },
          "best_case": {
            "type": "string",
            "title": "Best Case",
            "description": "Best case expected in the month."
          },
          "pipeline": {
            "type": "string",
            "title": "Pipeline",
            "description": "Pipeline expected in the month."
          }
        },
        "type": "object",
        "required": [
          "month",
          "quota",
          "closed",
          "commit",
          "best_case",
          "pipeline"
        ],
        "title": "ForecastMonth"
      },
      "ForecastPeriod": {
        "properties": {
          "revenue": {
            "type": "string",
            "title": "Revenue",
            "description": "Revenue, in the company's currency."
          },
          "expenses": {
            "type": "string",
            "title": "Expenses",
            "description": "Expenses, in the company's currency."
          },
          "net": {
            "type": "string",
            "title": "Net",
            "description": "Revenue less expenses: the net income."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The fiscal period, `YYYY-MM` (fiscal year and number)."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "Its first day."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Its last day."
          },
          "actual": {
            "type": "boolean",
            "title": "Actual",
            "description": "Closed: its figures are what was posted."
          },
          "scheduled": {
            "type": "boolean",
            "title": "Scheduled",
            "description": "Some of its figures are what is already scheduled (recurring invoices, subscriptions, recurring journals, depreciation) rather than the run rate."
          }
        },
        "type": "object",
        "required": [
          "revenue",
          "expenses",
          "net",
          "period",
          "start",
          "end",
          "actual",
          "scheduled"
        ],
        "title": "ForecastPeriod"
      },
      "ForecastReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The report's currency (quotas are in it)."
          },
          "rate_day": {
            "type": "string",
            "format": "date",
            "title": "Rate Day",
            "description": "The day whose ECB fixing converts the amounts."
          },
          "fixing_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fixing Date",
            "description": "The fixing used; null when there is none near the day (then every other currency is in `unconverted`)."
          },
          "unconverted": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unconverted",
            "description": "Currencies left out of the converted amounts."
          },
          "from_month": {
            "type": "string",
            "title": "From Month",
            "description": "First month, `YYYY-MM`."
          },
          "to_month": {
            "type": "string",
            "title": "To Month",
            "description": "Last month, `YYYY-MM`."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/ForecastRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "Per owner (and everyone with a quota), the highest quota first."
          },
          "total": {
            "$ref": "#/components/schemas/ForecastRow",
            "description": "Everyone."
          },
          "months": {
            "items": {
              "$ref": "#/components/schemas/ForecastMonth"
            },
            "type": "array",
            "title": "Months",
            "description": "Every month of the range, in order."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "rate_day",
          "fixing_date",
          "unconverted",
          "from_month",
          "to_month",
          "rows",
          "total",
          "months"
        ],
        "title": "ForecastReport",
        "examples": [
          {
            "currency": "CHF",
            "entity": "CH01",
            "fixing_date": "2026-10-23",
            "from_month": "2026-10",
            "months": [],
            "rate_day": "2026-10-23",
            "rows": [],
            "to_month": "2026-12",
            "total": {
              "attainment": "32.0",
              "best": "118000.00",
              "best_case": {
                "amount": "30000.00",
                "by_currency": [
                  {
                    "amount": "30000.00",
                    "currency": "CHF"
                  }
                ]
              },
              "closed": {
                "amount": "48000.00",
                "by_currency": [
                  {
                    "amount": "48000.00",
                    "currency": "CHF"
                  }
                ]
              },
              "commit": {
                "amount": "40000.00",
                "by_currency": [
                  {
                    "amount": "40000.00",
                    "currency": "CHF"
                  }
                ]
              },
              "deals": 9,
              "forecast": "88000.00",
              "gap": "102000.00",
              "key": "total",
              "late": 1,
              "pipeline": {
                "amount": "25000.00",
                "by_currency": [
                  {
                    "amount": "25000.00",
                    "currency": "CHF"
                  }
                ]
              },
              "quota": "150000.00",
              "undated": 2,
              "weighted": {
                "amount": "53750.00",
                "by_currency": [
                  {
                    "amount": "53750.00",
                    "currency": "CHF"
                  }
                ]
              }
            },
            "unconverted": []
          }
        ]
      },
      "ForecastRow": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "The owner's user id, `none` for no owner, `total`."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "The owner."
          },
          "quota": {
            "type": "string",
            "title": "Quota",
            "description": "Their quota for the months (0: none set)."
          },
          "closed": {
            "$ref": "#/components/schemas/Figure",
            "description": "Won in the months (by close day)."
          },
          "commit": {
            "$ref": "#/components/schemas/Figure",
            "description": "Open, expected in the months, category commit."
          },
          "best_case": {
            "$ref": "#/components/schemas/Figure",
            "description": "Open, expected in the months, category best case."
          },
          "pipeline": {
            "$ref": "#/components/schemas/Figure",
            "description": "Open, expected in the months, category pipeline."
          },
          "weighted": {
            "$ref": "#/components/schemas/Figure",
            "description": "Open, expected in the months and not omitted, weighted by probability."
          },
          "forecast": {
            "type": "string",
            "title": "Forecast",
            "description": "Closed plus commit, converted: the call."
          },
          "best": {
            "type": "string",
            "title": "Best",
            "description": "Closed plus commit plus best case, converted."
          },
          "attainment": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Attainment",
            "description": "Closed of quota, in percent (one decimal); null without a quota."
          },
          "gap": {
            "type": "string",
            "title": "Gap",
            "description": "Quota minus closed (negative: above quota)."
          },
          "deals": {
            "type": "integer",
            "title": "Deals",
            "description": "Open deals expected in the months (not omitted)."
          },
          "late": {
            "type": "integer",
            "title": "Late",
            "description": "Open deals whose expected close is before the months (not in the forecast)."
          },
          "undated": {
            "type": "integer",
            "title": "Undated",
            "description": "Open deals without an expected close."
          }
        },
        "type": "object",
        "required": [
          "key",
          "owner",
          "quota",
          "closed",
          "commit",
          "best_case",
          "pipeline",
          "weighted",
          "forecast",
          "best",
          "attainment",
          "gap",
          "deals",
          "late",
          "undated"
        ],
        "title": "ForecastRow"
      },
      "ForecastTotals": {
        "properties": {
          "revenue": {
            "type": "string",
            "title": "Revenue",
            "description": "Revenue, in the company's currency."
          },
          "expenses": {
            "type": "string",
            "title": "Expenses",
            "description": "Expenses, in the company's currency."
          },
          "net": {
            "type": "string",
            "title": "Net",
            "description": "Revenue less expenses: the net income."
          }
        },
        "type": "object",
        "required": [
          "revenue",
          "expenses",
          "net"
        ],
        "title": "ForecastTotals"
      },
      "ForecastWeek": {
        "properties": {
          "number": {
            "type": "integer",
            "title": "Number",
            "description": "1 (this week, from Monday) to 13."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "Its Monday."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Its Sunday."
          },
          "inflow": {
            "type": "string",
            "title": "Inflow",
            "description": "What comes in."
          },
          "outflow": {
            "type": "string",
            "title": "Outflow",
            "description": "What goes out, as a positive amount."
          },
          "net": {
            "type": "string",
            "title": "Net",
            "description": "Inflow less outflow."
          },
          "closing": {
            "type": "string",
            "title": "Closing",
            "description": "The cash at the week's end."
          },
          "by_source": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "By Source",
            "description": "The net amount of each source."
          }
        },
        "type": "object",
        "required": [
          "number",
          "start",
          "end",
          "inflow",
          "outflow",
          "net",
          "closing",
          "by_source"
        ],
        "title": "ForecastWeek"
      },
      "FormFieldIn": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80,
            "title": "Name",
            "description": "The field's key in the form, e.g. `name`."
          },
          "label": {
            "type": "string",
            "maxLength": 120,
            "title": "Label",
            "description": "The field's label on the screen."
          },
          "help": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 600
              },
              {
                "type": "null"
              }
            ],
            "title": "Help",
            "description": "The screen's explanation of the field."
          },
          "kind": {
            "type": "string",
            "enum": [
              "boolean",
              "choice",
              "number",
              "text"
            ],
            "title": "Kind",
            "description": "What the field takes.",
            "default": "text"
          },
          "options": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 60
              },
              {
                "type": "null"
              }
            ],
            "title": "Options",
            "description": "The values a `choice` field allows."
          },
          "value": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Value",
            "description": "What the person entered so far, if anything."
          }
        },
        "type": "object",
        "required": [
          "name",
          "label"
        ],
        "title": "FormFieldIn"
      },
      "FormSuggestionRequest": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company the form is for, e.g. `CH01`."
          },
          "form": {
            "type": "string",
            "maxLength": 300,
            "minLength": 3,
            "title": "Form",
            "description": "What the form creates, in a sentence, e.g. `A support queue`."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language the suggested texts are written in.",
            "default": "en"
          },
          "fields": {
            "items": {
              "$ref": "#/components/schemas/FormFieldIn"
            },
            "type": "array",
            "maxItems": 40,
            "minItems": 1,
            "title": "Fields",
            "description": "The form's fields, in screen order."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "form",
          "fields"
        ],
        "title": "FormSuggestionRequest",
        "examples": [
          {
            "entity": "CH01",
            "fields": [
              {
                "help": "What the team calls it",
                "label": "Name",
                "name": "name"
              },
              {
                "help": "Working hours to the first reply to an urgent case",
                "kind": "number",
                "label": "Urgent: first reply",
                "name": "urgent_first"
              }
            ],
            "form": "A support queue: where customer cases land",
            "language": "en"
          }
        ]
      },
      "FormSuggestions": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ready",
              "waiting"
            ],
            "title": "Status",
            "description": "`waiting`: no model answered in time; ask again after `retry_after_seconds`. Nothing was suggested."
          },
          "suggestions": {
            "items": {
              "$ref": "#/components/schemas/FieldSuggestion"
            },
            "type": "array",
            "title": "Suggestions",
            "description": "A value per field the model could propose; fields it left out are absent."
          },
          "retry_after_seconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Retry After Seconds",
            "description": "With `waiting`: when asking again may succeed."
          }
        },
        "type": "object",
        "required": [
          "status",
          "suggestions"
        ],
        "title": "FormSuggestions"
      },
      "FrameworkOption": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "The standard's id, the `standard` of `POST /v1/setup`."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Its name, e.g. `US GAAP`."
          },
          "framework": {
            "type": "string",
            "enum": [
              "ifrs",
              "local",
              "us_gaap"
            ],
            "title": "Framework",
            "description": "The entity's accounting framework it is recorded as."
          },
          "chart": {
            "type": "string",
            "title": "Chart",
            "description": "The chart template the company starts from."
          }
        },
        "type": "object",
        "required": [
          "id",
          "label",
          "framework",
          "chart"
        ],
        "title": "FrameworkOption"
      },
      "FxAccountingBasis": {
        "properties": {
          "series": {
            "type": "string",
            "title": "Series",
            "description": "`ecb`."
          },
          "use": {
            "type": "string",
            "title": "Use",
            "description": "What it is for: `booking`, the rate documents, payments and revaluation are translated at."
          },
          "fixing_date": {
            "type": "string",
            "format": "date",
            "title": "Fixing Date",
            "description": "The ECB fixing day used."
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/FxSourceRef"
            },
            "type": "array",
            "title": "Sources",
            "description": "The authority and where it publishes."
          }
        },
        "type": "object",
        "required": [
          "series",
          "use",
          "fixing_date",
          "sources"
        ],
        "title": "FxAccountingBasis"
      },
      "FxConversion": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "requested_date": {
            "type": "string",
            "format": "date",
            "title": "Requested Date",
            "description": "The date asked for (ISO 8601)."
          },
          "fixing_date": {
            "type": "string",
            "format": "date",
            "title": "Fixing Date",
            "description": "The ECB fixing day actually used: the latest on or before `requested_date`."
          },
          "fallback": {
            "type": "boolean",
            "title": "Fallback",
            "description": "True when `fixing_date` is earlier than `requested_date`: a weekend or a holiday has no fixing, so the previous one applies."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "The series: `ecb`, the euro reference rates."
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/FxSourceRef"
            },
            "type": "array",
            "title": "Sources",
            "description": "The authority and where it publishes."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The data-vNext dataset version that answered (an archived version can be pinned to reproduce the answer)."
          },
          "decimals": {
            "type": "integer",
            "title": "Decimals",
            "description": "Decimals of every rate: 10."
          },
          "rounding": {
            "type": "string",
            "title": "Rounding",
            "description": "How the last decimal is rounded: `half_even`, once, after the division."
          },
          "amount": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Amount",
            "description": "The amount converted, in `from_currency`."
          },
          "from_currency": {
            "type": "string",
            "title": "From Currency",
            "description": "The currency converted from."
          },
          "to_currency": {
            "type": "string",
            "title": "To Currency",
            "description": "The currency converted to."
          },
          "rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Rate",
            "description": "Units of `to_currency` per one `from_currency`, 10 decimals."
          },
          "inverse": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Inverse",
            "description": "Units of `from_currency` per one `to_currency`."
          },
          "converted": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Converted",
            "description": "`amount` times `rate`, rounded half-even to the minor unit of `to_currency`, as data-vNext's `/v1/fx/convert` does. Indicative: the books round half-up (`round_money`), so a booked amount can differ by one minor unit on an exact tie."
          },
          "path": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Path",
            "description": "The route: through EUR unless one currency is EUR."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "requested_date",
          "fixing_date",
          "fallback",
          "source",
          "sources",
          "dataset_version",
          "decimals",
          "rounding",
          "amount",
          "from_currency",
          "to_currency",
          "rate",
          "inverse",
          "converted",
          "path"
        ],
        "title": "FxConversion"
      },
      "FxExposure": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "requested_date": {
            "type": "string",
            "format": "date",
            "title": "Requested Date",
            "description": "The date asked for (ISO 8601)."
          },
          "fixing_date": {
            "type": "string",
            "format": "date",
            "title": "Fixing Date",
            "description": "The ECB fixing day actually used: the latest on or before `requested_date`."
          },
          "fallback": {
            "type": "boolean",
            "title": "Fallback",
            "description": "True when `fixing_date` is earlier than `requested_date`: a weekend or a holiday has no fixing, so the previous one applies."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "The series: `ecb`, the euro reference rates."
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/FxSourceRef"
            },
            "type": "array",
            "title": "Sources",
            "description": "The authority and where it publishes."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The data-vNext dataset version that answered (an archived version can be pinned to reproduce the answer)."
          },
          "decimals": {
            "type": "integer",
            "title": "Decimals",
            "description": "Decimals of every rate: 10."
          },
          "rounding": {
            "type": "string",
            "title": "Rounding",
            "description": "How the last decimal is rounded: `half_even`, once, after the division."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The company's functional currency."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/FxExposureRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "One row per foreign currency, by code."
          },
          "totals": {
            "$ref": "#/components/schemas/FxExposureTotals",
            "description": "The totals in the functional currency."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "requested_date",
          "fixing_date",
          "fallback",
          "source",
          "sources",
          "dataset_version",
          "decimals",
          "rounding",
          "functional_currency",
          "rows",
          "totals"
        ],
        "title": "FxExposure"
      },
      "FxExposureCell": {
        "properties": {
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Positions counted."
          },
          "booked": {
            "type": "string",
            "title": "Booked",
            "description": "What the books hold, in the functional currency."
          },
          "revalued": {
            "type": "string",
            "title": "Revalued",
            "description": "The value at the selected date's rate, in the functional currency, each position rounded half up to the minor unit as a revaluation books it."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`revalued` less `booked`: how far the balance moves if revalued."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The positions' sum in the transaction currency (credit notes count negative)."
          }
        },
        "type": "object",
        "required": [
          "count",
          "booked",
          "revalued",
          "difference",
          "amount"
        ],
        "title": "FxExposureCell"
      },
      "FxExposureItem": {
        "properties": {
          "side": {
            "type": "string",
            "enum": [
              "bank",
              "payables",
              "receivables"
            ],
            "title": "Side",
            "description": "`receivables`, `payables` or `bank`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The transaction currency."
          },
          "kind": {
            "type": "string",
            "enum": [
              "account",
              "document"
            ],
            "title": "Kind",
            "description": "`document` for an open item, `account` for a bank balance."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "The document number or the account code."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "The customer or vendor, or the account name."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The document's id, for an open item."
          },
          "account_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Code",
            "description": "The account's code, for a bank."
          },
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "The document's date."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Open amount or balance in the transaction currency (a credit note negative)."
          },
          "booked": {
            "type": "string",
            "title": "Booked",
            "description": "What the books hold, in the functional currency."
          },
          "revalued": {
            "type": "string",
            "title": "Revalued",
            "description": "The value at the selected date's rate."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`revalued` less `booked`."
          }
        },
        "type": "object",
        "required": [
          "side",
          "currency",
          "kind",
          "reference",
          "amount",
          "booked",
          "revalued",
          "difference"
        ],
        "title": "FxExposureItem"
      },
      "FxExposureItems": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "requested_date": {
            "type": "string",
            "format": "date",
            "title": "Requested Date",
            "description": "The date asked for."
          },
          "fixing_date": {
            "type": "string",
            "format": "date",
            "title": "Fixing Date",
            "description": "The ECB fixing day used."
          },
          "side": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "bank",
                  "payables",
                  "receivables"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Side",
            "description": "The side filtered on, if any."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The currency filtered on, if any."
          },
          "total": {
            "type": "integer",
            "title": "Total",
            "description": "How many positions match: the `count` of the matching cells of `/exposure`."
          },
          "limit": {
            "type": "integer",
            "title": "Limit",
            "description": "Page size."
          },
          "offset": {
            "type": "integer",
            "title": "Offset",
            "description": "Positions skipped."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/FxExposureItem"
            },
            "type": "array",
            "title": "Items",
            "description": "The matching positions by currency and reference."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "requested_date",
          "fixing_date",
          "total",
          "limit",
          "offset",
          "items"
        ],
        "title": "FxExposureItems"
      },
      "FxExposureRow": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code of the transaction currency."
          },
          "rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Rate",
            "description": "Units of the functional currency per one unit, 10 decimals."
          },
          "receivables": {
            "$ref": "#/components/schemas/FxExposureCell",
            "description": "Open customer invoices and credit notes."
          },
          "payables": {
            "$ref": "#/components/schemas/FxExposureCell",
            "description": "Open vendor bills and credit notes."
          },
          "bank": {
            "$ref": "#/components/schemas/FxExposureCell",
            "description": "Balances of the accounts held in the currency."
          },
          "unrealised": {
            "type": "string",
            "title": "Unrealised",
            "description": "The unrealised result a revaluation would post for the currency, as a gain (positive) or a loss: receivables and bank `difference` less payables `difference`."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "rate",
          "receivables",
          "payables",
          "bank",
          "unrealised"
        ],
        "title": "FxExposureRow"
      },
      "FxExposureTotals": {
        "properties": {
          "receivables": {
            "$ref": "#/components/schemas/FxSubtotal",
            "description": "Receivables in every foreign currency."
          },
          "payables": {
            "$ref": "#/components/schemas/FxSubtotal",
            "description": "Payables in every foreign currency."
          },
          "bank": {
            "$ref": "#/components/schemas/FxSubtotal",
            "description": "Foreign-currency bank balances."
          },
          "unrealised": {
            "type": "string",
            "title": "Unrealised",
            "description": "The unrealised result a revaluation at this date would post: the sum of the rows, equal to the balancing line of the period-end revaluation entry."
          }
        },
        "type": "object",
        "required": [
          "receivables",
          "payables",
          "bank",
          "unrealised"
        ],
        "title": "FxExposureTotals"
      },
      "FxExtreme": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "The fixing day."
          },
          "rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Rate",
            "description": "The rate on that day, 10 decimals."
          }
        },
        "type": "object",
        "required": [
          "date",
          "rate"
        ],
        "title": "FxExtreme"
      },
      "FxHistory": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "The currency priced: `1 base = rate quote`."
          },
          "quote": {
            "type": "string",
            "title": "Quote",
            "description": "The currency the rate is in."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "The series: `ecb`."
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/FxSourceRef"
            },
            "type": "array",
            "title": "Sources",
            "description": "The authority and where it publishes."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The data-vNext dataset version that answered."
          },
          "decimals": {
            "type": "integer",
            "title": "Decimals",
            "description": "Decimals of every rate: 10."
          },
          "rounding": {
            "type": "string",
            "title": "Rounding",
            "description": "How the last decimal is rounded: `half_even`."
          },
          "points": {
            "items": {
              "$ref": "#/components/schemas/FxPoint"
            },
            "type": "array",
            "title": "Points",
            "description": "The daily cross rate on every ECB fixing day of the range, oldest first. Weekends and holidays have no point."
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Number of points."
          },
          "first": {
            "$ref": "#/components/schemas/FxExtreme",
            "description": "The first rate of the range."
          },
          "last": {
            "$ref": "#/components/schemas/FxExtreme",
            "description": "The last rate of the range."
          },
          "minimum": {
            "$ref": "#/components/schemas/FxExtreme",
            "description": "The lowest rate and the first day it occurred."
          },
          "maximum": {
            "$ref": "#/components/schemas/FxExtreme",
            "description": "The highest rate and the first day it occurred."
          },
          "average": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Average",
            "description": "Arithmetic mean of the points, 10 decimals half-even: the method of the IAS 21 average, applied to the range shown."
          },
          "change": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Change",
            "description": "Last rate less first rate."
          },
          "change_percent": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Change Percent",
            "description": "`change` as a percentage of the first rate, 4 decimals."
          },
          "month": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FxMonthAverage"
              },
              {
                "type": "null"
              }
            ],
            "description": "The IAS 21 average and closing rate of the latest completed month in the range; null when data-vNext has no complete month of fixings for the pair."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "base",
          "quote",
          "start",
          "end",
          "source",
          "sources",
          "dataset_version",
          "decimals",
          "rounding",
          "points",
          "count",
          "first",
          "last",
          "minimum",
          "maximum",
          "average",
          "change",
          "change_percent"
        ],
        "title": "FxHistory"
      },
      "FxMatrix": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "requested_date": {
            "type": "string",
            "format": "date",
            "title": "Requested Date",
            "description": "The date asked for (ISO 8601)."
          },
          "fixing_date": {
            "type": "string",
            "format": "date",
            "title": "Fixing Date",
            "description": "The ECB fixing day actually used: the latest on or before `requested_date`."
          },
          "fallback": {
            "type": "boolean",
            "title": "Fallback",
            "description": "True when `fixing_date` is earlier than `requested_date`: a weekend or a holiday has no fixing, so the previous one applies."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "The series: `ecb`, the euro reference rates."
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/FxSourceRef"
            },
            "type": "array",
            "title": "Sources",
            "description": "The authority and where it publishes."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The data-vNext dataset version that answered (an archived version can be pinned to reproduce the answer)."
          },
          "decimals": {
            "type": "integer",
            "title": "Decimals",
            "description": "Decimals of every rate: 10."
          },
          "rounding": {
            "type": "string",
            "title": "Rounding",
            "description": "How the last decimal is rounded: `half_even`, once, after the division."
          },
          "reading": {
            "type": "string",
            "title": "Reading",
            "description": "How to read the matrix: `1 row = x column`, e.g. the row USD and the column CHF hold how many francs one dollar buys."
          },
          "method": {
            "type": "string",
            "title": "Method",
            "description": "`triangulated through EUR`: each cell is the ECB rate of the column currency divided by that of the row currency."
          },
          "currencies": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Currencies",
            "description": "The currencies, in the order of rows and columns."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/FxMatrixRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "One row per currency."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "requested_date",
          "fixing_date",
          "fallback",
          "source",
          "sources",
          "dataset_version",
          "decimals",
          "rounding",
          "reading",
          "method",
          "currencies",
          "rows"
        ],
        "title": "FxMatrix"
      },
      "FxMatrixRow": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The row currency: `1 row = x column`."
          },
          "rates": {
            "items": {
              "type": "string",
              "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
            },
            "type": "array",
            "title": "Rates",
            "description": "`rates[j]` is units of `columns[j]` per one unit of the row currency, 10 decimals; `1` on the diagonal."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "rates"
        ],
        "title": "FxMatrixRow"
      },
      "FxMonthAverage": {
        "properties": {
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The month, `YYYY-MM`: the latest completed one in range."
          },
          "average": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Average",
            "description": "IAS 21 average: the mean of the daily cross rates over the month's fixings, 10 decimals."
          },
          "closing": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Closing",
            "description": "IAS 21 closing rate: the last fixing on or before the month end, which is the rate the period-end revaluation uses."
          },
          "fixings": {
            "type": "integer",
            "title": "Fixings",
            "description": "Daily fixings in the average."
          },
          "first_fixing": {
            "type": "string",
            "format": "date",
            "title": "First Fixing",
            "description": "The first fixing day of the month."
          },
          "last_fixing": {
            "type": "string",
            "format": "date",
            "title": "Last Fixing",
            "description": "The last fixing day of the month."
          }
        },
        "type": "object",
        "required": [
          "period",
          "average",
          "closing",
          "fixings",
          "first_fixing",
          "last_fixing"
        ],
        "title": "FxMonthAverage",
        "description": "The IAS 21 rates of a completed calendar month, from data-vNext `/v1/fx/period-rates`:\nthe average revaluation-style reports use for income and expenses and the closing rate the\nrevaluation uses for balances."
      },
      "FxPoint": {
        "properties": {
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "The fixing day."
          },
          "rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Rate",
            "description": "Units of the quote currency per one base unit."
          }
        },
        "type": "object",
        "required": [
          "date",
          "rate"
        ],
        "title": "FxPoint"
      },
      "FxRateRow": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code of the currency."
          },
          "rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Rate",
            "description": "Units of the functional currency per one unit of `currency` (`1 currency = rate functional`), 10 decimals: the rate a revaluation uses."
          },
          "inverse": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Inverse",
            "description": "Units of `currency` per one unit of the functional currency, 10 decimals. Computed from the fixings, not as 1 / `rate`, so it carries no second rounding."
          },
          "in_use": {
            "type": "boolean",
            "title": "In Use",
            "description": "True when the company has documents, a bank account or open items in it."
          },
          "documents": {
            "type": "integer",
            "title": "Documents",
            "description": "Documents in the currency (drafts included)."
          },
          "bank_accounts": {
            "type": "integer",
            "title": "Bank Accounts",
            "description": "Active accounts held in the currency."
          },
          "open_items": {
            "type": "integer",
            "title": "Open Items",
            "description": "Posted documents in the currency that are still open."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "rate",
          "inverse",
          "in_use",
          "documents",
          "bank_accounts",
          "open_items"
        ],
        "title": "FxRateRow"
      },
      "FxRates": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "requested_date": {
            "type": "string",
            "format": "date",
            "title": "Requested Date",
            "description": "The date asked for (ISO 8601)."
          },
          "fixing_date": {
            "type": "string",
            "format": "date",
            "title": "Fixing Date",
            "description": "The ECB fixing day actually used: the latest on or before `requested_date`."
          },
          "fallback": {
            "type": "boolean",
            "title": "Fallback",
            "description": "True when `fixing_date` is earlier than `requested_date`: a weekend or a holiday has no fixing, so the previous one applies."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "The series: `ecb`, the euro reference rates."
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/FxSourceRef"
            },
            "type": "array",
            "title": "Sources",
            "description": "The authority and where it publishes."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The data-vNext dataset version that answered (an archived version can be pinned to reproduce the answer)."
          },
          "decimals": {
            "type": "integer",
            "title": "Decimals",
            "description": "Decimals of every rate: 10."
          },
          "rounding": {
            "type": "string",
            "title": "Rounding",
            "description": "How the last decimal is rounded: `half_even`, once, after the division."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The company's functional currency."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/FxRateRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "Every currency the ECB publishes except the functional one: the ones in use first, then the rest by code."
          },
          "in_use": {
            "type": "integer",
            "title": "In Use",
            "description": "How many of the rows are in use."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "requested_date",
          "fixing_date",
          "fallback",
          "source",
          "sources",
          "dataset_version",
          "decimals",
          "rounding",
          "functional_currency",
          "rows",
          "in_use"
        ],
        "title": "FxRates"
      },
      "FxSourceRef": {
        "properties": {
          "authority": {
            "type": "string",
            "title": "Authority",
            "description": "The publisher, e.g. `European Central Bank`."
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "The page the rates are published on."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The name of the publication or the legal basis; null if none."
          }
        },
        "type": "object",
        "required": [
          "authority"
        ],
        "title": "FxSourceRef",
        "description": "Where a rate comes from: the authority behind it and the page that publishes it."
      },
      "FxSubtotal": {
        "properties": {
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Positions counted."
          },
          "booked": {
            "type": "string",
            "title": "Booked",
            "description": "What the books hold, in the functional currency."
          },
          "revalued": {
            "type": "string",
            "title": "Revalued",
            "description": "The value at the selected date's rate, in the functional currency, each position rounded half up to the minor unit as a revaluation books it."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`revalued` less `booked`: how far the balance moves if revalued."
          }
        },
        "type": "object",
        "required": [
          "count",
          "booked",
          "revalued",
          "difference"
        ],
        "title": "FxSubtotal"
      },
      "FxTaxBasis": {
        "properties": {
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "The method the company's VAT settings use: `monthly` or `daily` (CH, BAZG), `monthly` or `ecb_daily` (DE). Null where no official rates apply."
          },
          "series": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Series",
            "description": "The data-vNext series, e.g. `ch-vat-monthly`, `de-vat-monthly`; `ecb` for the German daily ECB method. Null where no official rates apply."
          },
          "use": {
            "type": "string",
            "title": "Use",
            "description": "What it is for: `vat_return`, the rate for the VAT amounts and the turnover on the VAT return."
          },
          "legal_basis": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Legal Basis",
            "description": "The rule that prescribes it: `MWSTV Art. 45` (CH) or `UStG §16 Abs. 6` (DE)."
          },
          "authority": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FxSourceRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The authority that publishes the rates, from the source register; null where it lists none."
          }
        },
        "type": "object",
        "required": [
          "method",
          "series",
          "use",
          "legal_basis",
          "authority"
        ],
        "title": "FxTaxBasis"
      },
      "FxTaxRateRow": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code of the foreign currency."
          },
          "in_use": {
            "type": "boolean",
            "title": "In Use",
            "description": "True when the company uses the currency."
          },
          "accounting_rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Accounting Rate",
            "description": "ECB rate: units of the tax currency per one unit of `currency`, 10 decimals."
          },
          "status": {
            "type": "string",
            "enum": [
              "final",
              "provisional"
            ],
            "title": "Status",
            "description": "`final` when the official rate is published, `provisional` when it is not yet (or does not list the currency): `tax_rate` is then null and `reason` says why."
          },
          "tax_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Rate",
            "description": "The official rate as units of the tax currency per one unit of `currency` (the German rate, quoted the other way round, is inverted), 10 decimals; null while provisional."
          },
          "published_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published Rate",
            "description": "The rate as the authority publishes it, in `quoted_as`."
          },
          "quoted_as": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quoted As",
            "description": "How it is quoted: `CHF per 1 USD` or `USD per 1 EUR`."
          },
          "tax_period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Period",
            "description": "The month the official rate covers (`YYYY-MM`), if monthly."
          },
          "tax_fixing_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fixing Date",
            "description": "The publication day the official rate carries."
          },
          "difference": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Difference",
            "description": "`tax_rate` less `accounting_rate`: the part of a foreign-currency document's VAT that differs from its booked rate."
          },
          "difference_percent": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Difference Percent",
            "description": "`difference` as a percentage of `accounting_rate`."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why the official rate is missing, as data-vNext says it."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "in_use",
          "accounting_rate",
          "status"
        ],
        "title": "FxTaxRateRow"
      },
      "FxTaxRates": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "jurisdiction": {
            "type": "string",
            "title": "Jurisdiction",
            "description": "The entity's country, which decides the tax rate."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The entity's functional currency."
          },
          "requested_date": {
            "type": "string",
            "format": "date",
            "title": "Requested Date",
            "description": "The date asked for: the tax point."
          },
          "supported": {
            "type": "boolean",
            "title": "Supported",
            "description": "True when the country prescribes official VAT exchange rates and the entity books in its tax currency (CH in francs, DE in euros)."
          },
          "tax_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Currency",
            "description": "CHF or EUR; null where unsupported."
          },
          "accounting": {
            "$ref": "#/components/schemas/FxAccountingBasis",
            "description": "The ECB rate the books use."
          },
          "tax": {
            "$ref": "#/components/schemas/FxTaxBasis",
            "description": "The official VAT rate the return uses."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The data-vNext dataset version that answered."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/FxTaxRateRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "One row per currency, each with both rates; empty where unsupported."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "jurisdiction",
          "functional_currency",
          "requested_date",
          "supported",
          "tax_currency",
          "accounting",
          "tax",
          "dataset_version",
          "rows"
        ],
        "title": "FxTaxRates"
      },
      "GeneralLedger": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range (ISO 8601)."
          },
          "opening_balance": {
            "type": "string",
            "title": "Opening Balance",
            "description": "Balance before `start`, functional currency, in the account's normal direction."
          },
          "closing_balance": {
            "type": "string",
            "title": "Closing Balance",
            "description": "Balance after the last line of the range."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/LedgerLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The posted lines of the account in the range."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "account",
          "name",
          "start",
          "end",
          "opening_balance",
          "closing_balance",
          "lines"
        ],
        "title": "GeneralLedger"
      },
      "GoogleLogin": {
        "properties": {
          "credential": {
            "type": "string",
            "title": "Credential",
            "description": "Google ID token from Google Identity Services."
          },
          "org_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Org Id",
            "description": "Chosen organization."
          }
        },
        "type": "object",
        "required": [
          "credential"
        ],
        "title": "GoogleLogin",
        "examples": [
          {
            "credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ij..."
          }
        ]
      },
      "GrniLateBill": {
        "properties": {
          "order_id": {
            "type": "string",
            "format": "uuid",
            "title": "Order Id",
            "description": "Id of the purchase order."
          },
          "order_number": {
            "type": "string",
            "title": "Order Number",
            "description": "Number of the purchase order."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "Name of the vendor."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Number of the order line."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description of the order line."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Billed after the line was written off."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "order_number",
          "vendor_name",
          "line_no",
          "description",
          "quantity"
        ],
        "title": "GrniLateBill"
      },
      "GrniOpenLine": {
        "properties": {
          "order_id": {
            "type": "string",
            "format": "uuid",
            "title": "Order Id",
            "description": "Id of the purchase order."
          },
          "order_number": {
            "type": "string",
            "title": "Order Number",
            "description": "Number of the purchase order."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Vendor code."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "Name of the vendor."
          },
          "line_id": {
            "type": "string",
            "format": "uuid",
            "title": "Line Id",
            "description": "Id of the order line."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Number of the order line."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description of the order line."
          },
          "item": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item",
            "description": "Code of the stock item; null for none."
          },
          "last_receipt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Receipt",
            "description": "Day of the line's last receipt."
          },
          "received_quantity": {
            "type": "string",
            "title": "Received Quantity",
            "description": "Received up to the day."
          },
          "received_value": {
            "type": "string",
            "title": "Received Value",
            "description": "Its receipt value."
          },
          "cleared_quantity": {
            "type": "string",
            "title": "Cleared Quantity",
            "description": "Cleared by bills up to the day."
          },
          "cleared_value": {
            "type": "string",
            "title": "Cleared Value",
            "description": "The receipt value cleared."
          },
          "written_off_value": {
            "type": "string",
            "title": "Written Off Value",
            "description": "The receipt value written off up to the day, as never to be billed."
          },
          "open_quantity": {
            "type": "string",
            "title": "Open Quantity",
            "description": "Received, not billed, not written off."
          },
          "open_value": {
            "type": "string",
            "title": "Open Value",
            "description": "Received, not billed: the accrual."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "order_number",
          "vendor",
          "vendor_name",
          "line_id",
          "line_no",
          "description",
          "item",
          "last_receipt",
          "received_quantity",
          "received_value",
          "cleared_quantity",
          "cleared_value",
          "written_off_value",
          "open_quantity",
          "open_value"
        ],
        "title": "GrniOpenLine"
      },
      "GrniReportOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day, end of day."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency."
          },
          "accounts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Accounts",
            "description": "The GR/IR account codes."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/GrniOpenLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "Every order line with something received and not billed (or billed and sent back), oldest order first."
          },
          "billed_after_write_off": {
            "items": {
              "$ref": "#/components/schemas/GrniLateBill"
            },
            "type": "array",
            "title": "Billed After Write Off",
            "description": "Order lines billed up to the day after they were written off as never to be billed: to check with the vendor (a credit note if the bill is wrong)."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total received, not billed."
          },
          "ledger": {
            "type": "string",
            "title": "Ledger",
            "description": "Balance of the GR/IR accounts on the day (credit), from posted entries."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "Total less ledger: zero, since only receipts, their clearing and write-offs book the GR/IR account."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "as_of",
          "currency",
          "accounts",
          "lines",
          "billed_after_write_off",
          "total",
          "ledger",
          "difference"
        ],
        "title": "GrniReportOut"
      },
      "GrniWriteOffInput": {
        "properties": {
          "write_off_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Write Off Date",
            "description": "Day of the entry; default today (company-local)."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why it will never be billed; kept on the entry."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "type": "integer"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "The order lines to write off; default every line with something open."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "The account credited (debited for a debit balance), by code or id. Default: for a stock item the inventory changes account (role `inventory_adjustment`), for any other line its own account."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "GrniWriteOffInput",
        "examples": [
          {
            "lines": [
              2
            ],
            "reason": "Samples the vendor sent free of charge",
            "write_off_date": "2026-09-30"
          }
        ]
      },
      "GrniWriteOffLine": {
        "properties": {
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Number of the order line."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "The quantity written off."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "Its receipt value, taken off GR/IR."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "The account it goes to."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "quantity",
          "value",
          "account"
        ],
        "title": "GrniWriteOffLine"
      },
      "GrniWriteOffOut": {
        "properties": {
          "order_id": {
            "type": "string",
            "format": "uuid",
            "title": "Order Id",
            "description": "Id of the purchase order."
          },
          "order_number": {
            "type": "string",
            "title": "Order Number",
            "description": "Number of the purchase order."
          },
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "Id of the journal entry."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, or `pending_approval` while a second person decides it (the write-off counts once posted; a rejected one leaves the lines open)."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency of the entity."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/GrniWriteOffLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "Per order line written off."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total taken off GR/IR (negative for a debit balance)."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "order_number",
          "entry_id",
          "status",
          "currency",
          "lines",
          "total"
        ],
        "title": "GrniWriteOffOut"
      },
      "GroupBalanceSheet": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the run."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The group date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The reporting currency."
          },
          "framework": {
            "type": "string",
            "enum": [
              "fer",
              "hgb",
              "ifrs"
            ],
            "title": "Framework",
            "description": "The framework of the run."
          },
          "complete": {
            "type": "boolean",
            "title": "Complete",
            "description": "False while the run has a blocking exception."
          },
          "eliminations_applied": {
            "type": "boolean",
            "title": "Eliminations Applied",
            "description": "True when intragroup items are eliminated (`eliminations` names the rules); false for a run made before the eliminations existed, which is the aggregate of the entities."
          },
          "assets": {
            "items": {
              "$ref": "#/components/schemas/StatementLine"
            },
            "type": "array",
            "title": "Assets",
            "description": "Asset lines."
          },
          "liabilities": {
            "items": {
              "$ref": "#/components/schemas/StatementLine"
            },
            "type": "array",
            "title": "Liabilities",
            "description": "Liability lines."
          },
          "equity": {
            "items": {
              "$ref": "#/components/schemas/StatementLine"
            },
            "type": "array",
            "title": "Equity",
            "description": "Equity lines: capital, retained earnings, the results of earlier years not yet appropriated, the translation reserve (the owners' share) and the non-controlling interests (`bs.equity.nci`, including their share of the year's result; IFRS 10.22)."
          },
          "result_of_year": {
            "type": "string",
            "title": "Result Of Year",
            "description": "The profit (positive) or loss of the group year attributable to the owners of the parent: the profit and loss lines less the share of the non-controlling interests, which is inside `bs.equity.nci`."
          },
          "total_assets": {
            "type": "string",
            "title": "Total Assets",
            "description": "Total assets."
          },
          "total_liabilities": {
            "type": "string",
            "title": "Total Liabilities",
            "description": "Total liabilities."
          },
          "total_equity": {
            "type": "string",
            "title": "Total Equity",
            "description": "Equity lines plus the result of the year."
          },
          "after_equity": {
            "items": {
              "$ref": "#/components/schemas/StatementLine"
            },
            "type": "array",
            "title": "After Equity",
            "description": "Lines shown after equity, neither liabilities nor equity: under HGB the negative difference from capital consolidation (section 301 para. 3 HGB)."
          },
          "total_after_equity": {
            "type": "string",
            "title": "Total After Equity",
            "description": "The sum of `after_equity`.",
            "default": "0.00"
          },
          "balanced": {
            "type": "boolean",
            "title": "Balanced",
            "description": "True when assets equal liabilities plus equity plus the lines after equity."
          }
        },
        "type": "object",
        "required": [
          "run",
          "as_of",
          "currency",
          "framework",
          "complete",
          "eliminations_applied",
          "assets",
          "liabilities",
          "equity",
          "result_of_year",
          "total_assets",
          "total_liabilities",
          "total_equity",
          "balanced"
        ],
        "title": "GroupBalanceSheet"
      },
      "GroupCashFlow": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the consolidation run, the end of the statement."
          },
          "opening_run": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opening Run",
            "description": "The run at the end of the previous year the statement starts from; null when no entity of the group had books before the year, so the group starts from nothing."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "The first day of the group year (ISO 8601)."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The run's date (ISO 8601)."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The reporting currency; all amounts are in it."
          },
          "framework": {
            "type": "string",
            "title": "Framework",
            "description": "The framework the group reports under."
          },
          "complete": {
            "type": "boolean",
            "title": "Complete",
            "description": "False while either run has a blocking exception."
          },
          "eliminations_applied": {
            "type": "boolean",
            "title": "Eliminations Applied",
            "description": "True when the run eliminates the intragroup items (as its statements)."
          },
          "opening_cash": {
            "type": "string",
            "title": "Opening Cash",
            "description": "The group's cash at the start (the opening run's)."
          },
          "sections": {
            "items": {
              "$ref": "#/components/schemas/CashFlowSection"
            },
            "type": "array",
            "title": "Sections",
            "description": "Operating, investing and financing activities from the change of each group report line, then the effect of exchange rates on cash held in other currencies."
          },
          "net_change": {
            "type": "string",
            "title": "Net Change",
            "description": "The sum of the sections."
          },
          "closing_cash": {
            "type": "string",
            "title": "Closing Cash",
            "description": "The group's cash at the run's date."
          },
          "balanced": {
            "type": "boolean",
            "title": "Balanced",
            "description": "True when the opening cash plus the net change is the closing cash."
          }
        },
        "type": "object",
        "required": [
          "run",
          "opening_run",
          "start",
          "as_of",
          "currency",
          "framework",
          "complete",
          "eliminations_applied",
          "opening_cash",
          "sections",
          "net_change",
          "closing_cash",
          "balanced"
        ],
        "title": "GroupCashFlow"
      },
      "GroupCheck": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Check id: `run` (a run exists at the date), `periods_closed` (no member period starting on or before the date is open), `ic_reconciled` (every relationship between two members agrees within its tolerance), `rates_available`, `report_lines` (every account maps to the group vocabulary), `ic_eliminated` (every elimination's sides agree within the group's tolerance), `cta_reconciled`, `balanced` (consolidated assets equal liabilities plus equity), `opening_position` (a member consolidated after its acquisition has a stated opening position), `capital_consolidated` (the investment in every subsidiary is eliminated against its equity at acquisition, with goodwill and non-controlling interests), `nci_attributed` (net income equals the owners' plus the non-controlling interests' share), `adjustments_approved` and `final_run_current` (later slices: `n/a`)."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the check verifies."
          },
          "status": {
            "type": "string",
            "enum": [
              "fail",
              "n/a",
              "pass",
              "warn"
            ],
            "title": "Status",
            "description": "`pass`, `fail` (a final run could not be made), `warn` (to know) or `n/a`."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "The result in English words."
          },
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "The result by a stable code (`erp.contracts.words.GROUP_CHECKS`): the screens word it as `consolidation.check.<code>` in the person's language."
          },
          "details": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Details",
            "description": "The values the words of `code` name, by name: amounts as decimal strings, days as ISO dates, lists, or reasons with their own `words`, `code`, `details` and `text` (such as the run's exceptions a check lists)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "title",
          "status",
          "detail"
        ],
        "title": "GroupCheck"
      },
      "GroupChecklist": {
        "properties": {
          "group": {
            "type": "string",
            "title": "Group",
            "description": "Code of the group."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The group date."
          },
          "run": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Run",
            "description": "The run the run-based checks read: the latest at the date (null if none)."
          },
          "run_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Run Version",
            "description": "Its version; null without a run."
          },
          "ready": {
            "type": "boolean",
            "title": "Ready",
            "description": "True when no check has the status `fail`."
          },
          "checks": {
            "items": {
              "$ref": "#/components/schemas/GroupCheck"
            },
            "type": "array",
            "title": "Checks",
            "description": "The checks in the order evaluated."
          }
        },
        "type": "object",
        "required": [
          "group",
          "as_of",
          "run",
          "run_version",
          "ready",
          "checks"
        ],
        "title": "GroupChecklist"
      },
      "GroupInput": {
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,29}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "The group's own code, unique in the organization (letters, digits, `.`, `_`, `-`, at most 30 characters). Omitted: made from the name (`Demo Group` is `DEMO-GROUP`, with `-2` when taken)."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "The group's name."
          },
          "parent_entity": {
            "type": "string",
            "title": "Parent Entity",
            "description": "Code of the parent entity: the entity that controls the others. It is in the group without being a member, and is not translated."
          },
          "reporting_currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reporting Currency",
            "description": "The presentation currency (ISO 4217). In this version it is the parent's functional currency: the parent is carried over unchanged. Omitted: that currency."
          },
          "framework": {
            "type": "string",
            "enum": [
              "fer",
              "hgb",
              "ifrs"
            ],
            "title": "Framework",
            "description": "The framework the group reports under: `ifrs`, `fer` (Swiss GAAP FER 30) or `hgb` (sections 290 to 315e HGB). A run under a framework whose rules have not been checked against its standard is refused (`framework_unverified`, `framework_not_implemented`); today all three run."
          },
          "goodwill_policy": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "amortise",
                  "impairment_only",
                  "offset_equity"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Goodwill Policy",
            "description": "How goodwill is treated: `impairment_only` (IFRS), `offset_equity` (FER) or `amortise` (FER, HGB); default: the framework's first. It must be one the framework allows."
          },
          "goodwill_years": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 20.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Goodwill Years",
            "description": "The useful life of goodwill in years, for the policies that take one: `amortise`, and under `fer` also `offset_equity` (the notes show a theoretical capitalisation over it). Left empty, the framework's life for goodwill whose life cannot be determined: 5 years under `fer`, 10 under `hgb`. At most 20; null for `impairment_only`."
          },
          "ic_tolerance_amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Ic Tolerance Amount",
            "description": "The difference between two sides of an intragroup balance, or of intragroup income and expense, that is still accepted, in the reporting currency: a residual of an elimination whose sides do not agree is the blocking exception `ic_difference` above it and a warning within it.",
            "default": "1"
          }
        },
        "type": "object",
        "required": [
          "name",
          "parent_entity",
          "framework"
        ],
        "title": "GroupInput",
        "examples": [
          {
            "code": "DEMO",
            "framework": "ifrs",
            "name": "Demo Group",
            "parent_entity": "CH01",
            "reporting_currency": "CHF"
          }
        ]
      },
      "GroupOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the group."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The group's code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The group's name."
          },
          "parent_entity": {
            "type": "string",
            "title": "Parent Entity",
            "description": "Code of the parent entity."
          },
          "reporting_currency": {
            "type": "string",
            "title": "Reporting Currency",
            "description": "The presentation currency."
          },
          "framework": {
            "type": "string",
            "enum": [
              "fer",
              "hgb",
              "ifrs"
            ],
            "title": "Framework",
            "description": "The framework the group reports under."
          },
          "framework_verified": {
            "type": "boolean",
            "title": "Framework Verified",
            "description": "True when the framework's sources have been read and cited, so a run is allowed."
          },
          "framework_implemented": {
            "type": "boolean",
            "title": "Framework Implemented",
            "description": "False for a framework that is documented only."
          },
          "goodwill_policy": {
            "type": "string",
            "enum": [
              "amortise",
              "impairment_only",
              "offset_equity"
            ],
            "title": "Goodwill Policy",
            "description": "The goodwill policy."
          },
          "goodwill_years": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Goodwill Years",
            "description": "The useful life of goodwill in years (amortised, or under `fer` offset against equity for the theoretical capitalisation), if any."
          },
          "ic_tolerance_amount": {
            "type": "string",
            "title": "Ic Tolerance Amount",
            "description": "The tolerance of intragroup differences."
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/MemberOut"
            },
            "type": "array",
            "title": "Members",
            "description": "The version in force today of every subsidiary, by entity code."
          },
          "pending": {
            "items": {
              "$ref": "#/components/schemas/PendingMember"
            },
            "type": "array",
            "title": "Pending",
            "description": "Member versions that wait for a second person's approval."
          },
          "runs": {
            "type": "integer",
            "title": "Runs",
            "description": "How many runs the group has (`GET .../runs` lists them)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created the group, as an actor object."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was created (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "parent_entity",
          "reporting_currency",
          "framework",
          "framework_verified",
          "framework_implemented",
          "goodwill_policy",
          "goodwill_years",
          "ic_tolerance_amount",
          "members",
          "pending",
          "runs",
          "created_by",
          "created_at"
        ],
        "title": "GroupOut"
      },
      "GroupPartyOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity whose books hold the party."
          },
          "kind": {
            "type": "string",
            "enum": [
              "customer",
              "vendor"
            ],
            "title": "Kind",
            "description": "`customer` or `vendor`."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The party's code, e.g. `IC-DE01`."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the party."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`active`: the relationship's approval activated it."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "kind",
          "code",
          "party_id",
          "status"
        ],
        "title": "GroupPartyOut"
      },
      "GroupProfitAndLoss": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the run."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The group date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The reporting currency."
          },
          "framework": {
            "type": "string",
            "enum": [
              "fer",
              "hgb",
              "ifrs"
            ],
            "title": "Framework",
            "description": "The framework of the run."
          },
          "complete": {
            "type": "boolean",
            "title": "Complete",
            "description": "False while the run has a blocking exception."
          },
          "eliminations_applied": {
            "type": "boolean",
            "title": "Eliminations Applied",
            "description": "True when intragroup items are eliminated (`eliminations` names the rules); false for a run made before the eliminations existed, which is the aggregate of the entities."
          },
          "year_start": {
            "type": "string",
            "format": "date",
            "title": "Year Start",
            "description": "The first day of the group year: 1 January."
          },
          "revenue": {
            "items": {
              "$ref": "#/components/schemas/StatementLine"
            },
            "type": "array",
            "title": "Revenue",
            "description": "Revenue lines."
          },
          "expenses": {
            "items": {
              "$ref": "#/components/schemas/StatementLine"
            },
            "type": "array",
            "title": "Expenses",
            "description": "Expense lines."
          },
          "total_revenue": {
            "type": "string",
            "title": "Total Revenue",
            "description": "Total revenue."
          },
          "total_expenses": {
            "type": "string",
            "title": "Total Expenses",
            "description": "Total expenses."
          },
          "net_income": {
            "type": "string",
            "title": "Net Income",
            "description": "Revenue less expenses: the group's profit or loss, before its attribution."
          },
          "attributable_to_nci": {
            "type": "string",
            "title": "Attributable To Nci",
            "description": "The part of `net_income` attributable to non-controlling interests (rule E5; IFRS 10.B94, IAS 1.81B). It is not an expense.",
            "default": "0.00"
          },
          "attributable_to_owners": {
            "type": "string",
            "title": "Attributable To Owners",
            "description": "The part attributable to the owners of the parent: `net_income` less `attributable_to_nci`; the balance sheet's result of the year.",
            "default": "0.00"
          }
        },
        "type": "object",
        "required": [
          "run",
          "as_of",
          "currency",
          "framework",
          "complete",
          "eliminations_applied",
          "year_start",
          "revenue",
          "expenses",
          "total_revenue",
          "total_expenses",
          "net_income"
        ],
        "title": "GroupProfitAndLoss"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
          }
        },
        "type": "object",
        "title": "HTTPValidationError"
      },
      "HandOverInput": {
        "properties": {
          "from_user_id": {
            "type": "string",
            "format": "uuid",
            "title": "From User Id",
            "description": "Whose records (`GET /v1/people`)."
          },
          "to_user_id": {
            "type": "string",
            "format": "uuid",
            "title": "To User Id",
            "description": "Who gets them."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Only this company's records (code or id); omitted: every one."
          }
        },
        "type": "object",
        "required": [
          "from_user_id",
          "to_user_id"
        ],
        "title": "HandOverInput",
        "examples": [
          {
            "from_user_id": "8b1f2c3d-4e5f-4a6b-9c7d-8e9f0a1b2c3d",
            "to_user_id": "9c2a3b4c-5d6e-4f7a-8b9c-0d1e2f3a4b5c"
          }
        ]
      },
      "HandOverOut": {
        "properties": {
          "customers": {
            "type": "integer",
            "title": "Customers",
            "description": "How many customers changed owner."
          },
          "contacts": {
            "type": "integer",
            "title": "Contacts",
            "description": "How many contacts."
          },
          "deals": {
            "type": "integer",
            "title": "Deals",
            "description": "How many deals (open, won and lost)."
          },
          "open_tasks_left": {
            "type": "integer",
            "title": "Open Tasks Left",
            "description": "Open tasks still assigned to the person handing over: a task keeps its assignee (an activity never changes); the new owner sees them on the deals and customers."
          }
        },
        "type": "object",
        "required": [
          "customers",
          "contacts",
          "deals",
          "open_tasks_left"
        ],
        "title": "HandOverOut"
      },
      "Handoff": {
        "properties": {
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "What kind of step, for a screen to word it: `approve` (what waits for a second person), `match_lines` (bank lines to match by hand), `reconcile_account` (mark a bank account reconciled), `activate_vendors` (new vendors whose bills wait for them), `finish_bills` (draft bills to finish by hand), `approve_bills` (bills waiting for a second person), `approve_differences` (bills that differ from their purchase orders); `bill_subscriptions`, `invoice_deliveries`, `invoice_stays`, `mend_recurring`, `issue_invoices`, `approve_invoices`, `send_invoices` (invoicing); `send_reminders`, `send_letters`, `withdraw_letters`, `collect_invoices`, `approve_collections`, `release_collections` (getting paid); `pay_bills` (bills due that Autopilot left to a person), `release_payments` (payments to send to the bank), `book_recurring` (recurring journals it could not book), `run_depreciation` (a month's depreciation it could not run; `ref` is the period, e.g. `2026-09`); `approve_close` (approvals that hold the close), `close_checks` (close checks of a month left to a person), `close_period` (close a month whose checklist passes), `prepare_vat` (a VAT return that could not be prepared), `finalise_vat`, `approve_vat`, `submit_vat`, `amend_vat` (a VAT return's next step), `ic_differences` (intercompany differences to resolve), `group_checks` (a group's close checks that fail), `read_pack` (the month's report pack names blockers)."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the person does, in English, e.g. `Approve the bank postings that wait for a second person.`"
          },
          "path": {
            "type": "string",
            "title": "Path",
            "description": "Where in the app they do it, e.g. `/approvals?entity=CH01`."
          },
          "ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ref",
            "description": "What it is about where an outcome has several, e.g. the account code of a bank account, a month (`2026-09`), a VAT return's reference or a group's code."
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Count",
            "description": "How many items it covers, if counted."
          },
          "due": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due",
            "description": "By when it is to be done, if there is a day: the close calendar's working day for closing a month, a VAT return's due date."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "title",
          "path"
        ],
        "title": "Handoff"
      },
      "HubSpotAuthorize": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company.",
            "examples": [
              "CH01"
            ]
          },
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "marketingqualifiedlead",
              "salesqualifiedlead"
            ],
            "title": "Stage",
            "description": "The lifecycle stage at which a HubSpot contact becomes a lead here: `lead`, `marketingqualifiedlead` (the default) or `salesqualifiedlead`. Contacts at that stage or a later one before `opportunity` come in.",
            "default": "marketingqualifiedlead"
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who owns a lead whose HubSpot owner is not a person here (`GET /v1/people`); none: Autopilot or a person gives it one."
          }
        },
        "type": "object",
        "required": [
          "entity"
        ],
        "title": "HubSpotAuthorize",
        "examples": [
          {
            "entity": "CH01",
            "stage": "marketingqualifiedlead"
          }
        ]
      },
      "HubSpotAuthorizeOut": {
        "properties": {
          "url": {
            "type": "string",
            "title": "Url",
            "description": "HubSpot's consent page: open it in the browser."
          },
          "redirect_uri": {
            "type": "string",
            "title": "Redirect Uri",
            "description": "Where HubSpot sends the browser back."
          }
        },
        "type": "object",
        "required": [
          "url",
          "redirect_uri"
        ],
        "title": "HubSpotAuthorizeOut"
      },
      "HubSpotConnection": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the connection."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company whose leads the contacts become."
          },
          "portal_id": {
            "type": "integer",
            "title": "Portal Id",
            "description": "HubSpot's id of the account (the Hub ID)."
          },
          "account_url": {
            "type": "string",
            "title": "Account Url",
            "description": "The account's contacts in HubSpot."
          },
          "method": {
            "type": "string",
            "enum": [
              "key",
              "oauth"
            ],
            "title": "Method",
            "description": "`oauth`: connected on HubSpot's consent page; `key`: with a private app's access token."
          },
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "marketingqualifiedlead",
              "salesqualifiedlead"
            ],
            "title": "Stage",
            "description": "The lifecycle stage at which a HubSpot contact becomes a lead here: `lead`, `marketingqualifiedlead` (the default) or `salesqualifiedlead`. Contacts at that stage or a later one before `opportunity` come in."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who owns a lead whose HubSpot owner is not a person here (`GET /v1/people`); none: Autopilot or a person gives it one."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "reconnect"
            ],
            "title": "Status",
            "description": "`reconnect`: HubSpot stopped accepting the token; connect again."
          },
          "read_to": {
            "type": "string",
            "format": "date-time",
            "title": "Read To",
            "description": "HubSpot's contacts are read up to here (UTC)."
          },
          "last_sync_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Sync At",
            "description": "When HubSpot was last read (UTC)."
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error",
            "description": "Why the last round failed, in plain words."
          },
          "leads": {
            "type": "integer",
            "title": "Leads",
            "description": "Leads that came from this account."
          },
          "linked_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Linked By",
            "description": "Who connected it."
          },
          "linked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Linked At",
            "description": "When it was connected (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "portal_id",
          "account_url",
          "method",
          "stage",
          "owner",
          "status",
          "read_to",
          "last_sync_at",
          "last_error",
          "leads",
          "linked_by",
          "linked_at"
        ],
        "title": "HubSpotConnection"
      },
      "HubSpotKeyInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company.",
            "examples": [
              "CH01"
            ]
          },
          "access_token": {
            "type": "string",
            "maxLength": 500,
            "minLength": 10,
            "title": "Access Token",
            "description": "The access token of a private app in the company's HubSpot with the scopes of `GET /v1/hubspot`. Kept sealed, never shown again."
          },
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "marketingqualifiedlead",
              "salesqualifiedlead"
            ],
            "title": "Stage",
            "description": "The lifecycle stage at which a HubSpot contact becomes a lead here: `lead`, `marketingqualifiedlead` (the default) or `salesqualifiedlead`. Contacts at that stage or a later one before `opportunity` come in.",
            "default": "marketingqualifiedlead"
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who owns a lead whose HubSpot owner is not a person here (`GET /v1/people`); none: Autopilot or a person gives it one."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "access_token"
        ],
        "title": "HubSpotKeyInput",
        "examples": [
          {
            "access_token": "pat-eu1-0b9c4d2e-7f1a-4c3b-9e8d-1a2b3c4d5e6f",
            "entity": "CH01",
            "stage": "marketingqualifiedlead"
          }
        ]
      },
      "HubSpotOAuthInput": {
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 1,
            "title": "Code",
            "description": "HubSpot's one-time `code`."
          },
          "state": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 1,
            "title": "State",
            "description": "The `state` HubSpot returned."
          }
        },
        "type": "object",
        "required": [
          "code",
          "state"
        ],
        "title": "HubSpotOAuthInput",
        "examples": [
          {
            "code": "na1-6a2b-…",
            "state": "eyJvcmciOiI….Xq3v…"
          }
        ]
      },
      "HubSpotSetup": {
        "properties": {
          "available": {
            "type": "boolean",
            "title": "Available",
            "description": "Whether HubSpot can be connected on this system (false: tokens could not be kept sealed)."
          },
          "oauth": {
            "type": "boolean",
            "title": "Oauth",
            "description": "Whether HubSpot's consent page can be used (this system has its HubSpot app); else connect with a private app's access token."
          },
          "client_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Id",
            "description": "Stabiso's HubSpot app, when there is one."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "What Stabiso needs: tick these on a private app."
          },
          "connections": {
            "items": {
              "$ref": "#/components/schemas/HubSpotConnection"
            },
            "type": "array",
            "title": "Connections",
            "description": "The companies connected."
          }
        },
        "type": "object",
        "required": [
          "available",
          "oauth",
          "client_id",
          "scopes",
          "connections"
        ],
        "title": "HubSpotSetup"
      },
      "HubSpotSyncOut": {
        "properties": {
          "read": {
            "type": "integer",
            "title": "Read",
            "description": "Contacts read from HubSpot."
          },
          "new_leads": {
            "type": "integer",
            "title": "New Leads",
            "description": "Leads made of them."
          },
          "updated_leads": {
            "type": "integer",
            "title": "Updated Leads",
            "description": "New leads that HubSpot's changes updated."
          },
          "sent": {
            "type": "integer",
            "title": "Sent",
            "description": "Contacts that Stabiso's news of their lead was sent to."
          },
          "connection": {
            "$ref": "#/components/schemas/HubSpotConnection",
            "description": "The connection after the round."
          }
        },
        "type": "object",
        "required": [
          "read",
          "new_leads",
          "updated_leads",
          "sent",
          "connection"
        ],
        "title": "HubSpotSyncOut"
      },
      "HubSpotUpdate": {
        "properties": {
          "stage": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "lead",
                  "marketingqualifiedlead",
                  "salesqualifiedlead"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Stage",
            "description": "The lifecycle stage at which a HubSpot contact becomes a lead here: `lead`, `marketingqualifiedlead` (the default) or `salesqualifiedlead`. Contacts at that stage or a later one before `opportunity` come in."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "string",
                "const": ""
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who owns a lead whose HubSpot owner is not a person here (`GET /v1/people`); none: Autopilot or a person gives it one. `\"\"` clears."
          }
        },
        "type": "object",
        "title": "HubSpotUpdate",
        "examples": [
          {
            "owner_user_id": "",
            "stage": "lead"
          }
        ]
      },
      "IcBlock": {
        "properties": {
          "link_id": {
            "type": "string",
            "format": "uuid",
            "title": "Link Id",
            "description": "Id of the link (`GET /v1/ic/links/{id}`)."
          },
          "role": {
            "type": "string",
            "enum": [
              "mirror",
              "origin"
            ],
            "title": "Role",
            "description": "`origin`: the invoice or credit note that was posted and mirrored; `mirror`: the document made from it in the other entity, which that entity accepts."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "The link's status: `pending`, `waiting`, `drafted`, `accepted` or `rejected`."
          },
          "partner_entity": {
            "type": "string",
            "title": "Partner Entity",
            "description": "Code of the other entity, the party this document is."
          },
          "other_document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Other Document Id",
            "description": "The document at the other end of the link; null while it was not made."
          }
        },
        "type": "object",
        "required": [
          "link_id",
          "role",
          "status",
          "partner_entity",
          "other_document_id"
        ],
        "title": "IcBlock",
        "description": "What a document of a group entity's customer or vendor is in an intercompany link\n(ADR-0025)."
      },
      "Identifier": {
        "properties": {
          "value": {
            "type": "string",
            "title": "Value",
            "description": "The identifier, e.g. a VAT number or an IBAN."
          },
          "scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scheme",
            "description": "The identification scheme (ISO 6523 ICD or EAS code); null when none."
          }
        },
        "type": "object",
        "required": [
          "value"
        ],
        "title": "Identifier"
      },
      "IgnoreRequest": {
        "properties": {
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why the line needs no booking, e.g. `Internal transfer, booked on 1020`; required (refused with `ignore_reason_missing` when empty).",
            "default": ""
          }
        },
        "type": "object",
        "title": "IgnoreRequest",
        "examples": [
          {
            "reason": "Internal transfer, booked on 1020"
          }
        ]
      },
      "ImpairmentInput": {
        "properties": {
          "impairment_date": {
            "type": "string",
            "format": "date",
            "title": "Impairment Date",
            "description": "Day of the impairment, ISO 8601; the entry is dated on it and its period must be open."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "The write-down, in the company's currency, at most the carrying amount."
          },
          "recoverable_amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recoverable Amount",
            "description": "Or the value the asset is written down to (its recoverable amount, IAS 36.59): the write-down is the carrying amount less it. Give this or `amount`."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the asset lost value, e.g. damage, obsolescence (kept with the change)."
          }
        },
        "type": "object",
        "required": [
          "impairment_date",
          "reason"
        ],
        "title": "ImpairmentInput",
        "examples": [
          {
            "impairment_date": "2026-10-31",
            "reason": "Machine damaged by water; repair not economic",
            "recoverable_amount": "6000.00"
          }
        ]
      },
      "ImpairmentReversalInput": {
        "properties": {
          "reversal_date": {
            "type": "string",
            "format": "date",
            "title": "Reversal Date",
            "description": "Day of the reversal, ISO 8601; the entry is dated on it and its period must be open."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "The write-up, in the company's currency, at most what the asset may be written up by (the value it would have, net of depreciation, had it not been impaired)."
          },
          "recoverable_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recoverable Amount",
            "description": "Or the asset's recoverable amount now: the write-up is what it is above the carrying amount, at most what the asset may be written up by. Give this or `amount`."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the reasons for the impairment no longer apply (kept with the change)."
          }
        },
        "type": "object",
        "required": [
          "reversal_date",
          "reason"
        ],
        "title": "ImpairmentReversalInput",
        "examples": [
          {
            "reason": "Market for the machine recovered; valuation of 20 December 2026",
            "recoverable_amount": "11000.00",
            "reversal_date": "2026-12-31"
          }
        ]
      },
      "ImportEntry": {
        "properties": {
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "Id (uuid) of the journal entry."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, or `pending_approval` when the approval policy sends it to a second person."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "The entry number once posted; null before."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request (`GET /v1/approvals`) while it waits; null otherwise."
          }
        },
        "type": "object",
        "required": [
          "entry_id",
          "status",
          "number",
          "approval_id"
        ],
        "title": "ImportEntry",
        "description": "The opening entry an `opening_balances` import posted or queued."
      },
      "ImportIssue": {
        "properties": {
          "line": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line",
            "description": "The row in the file (the header is row 1); null for a problem with the file as a whole or with the entry built from all rows."
          },
          "column": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Column",
            "description": "The column of the template the problem is in; null when it is about the row or the file as a whole."
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "What is wrong, and how to fix it."
          }
        },
        "type": "object",
        "required": [
          "line",
          "column",
          "message"
        ],
        "title": "ImportIssue",
        "description": "One problem found in the file, or one thing worth knowing."
      },
      "ImportResult": {
        "properties": {
          "statement_id": {
            "type": "string",
            "format": "uuid",
            "title": "Statement Id",
            "description": "Id of the stored statement (`GET .../bank-statements`)."
          },
          "statement_ref": {
            "type": "string",
            "title": "Statement Ref",
            "description": "The statement's reference as given by the bank; for a CSV file its account and dates, e.g. `CSV 1020 01.09.2026-30.09.2026`."
          },
          "imported": {
            "type": "integer",
            "title": "Imported",
            "description": "Number of lines stored."
          },
          "duplicates": {
            "type": "integer",
            "title": "Duplicates",
            "description": "Number of lines skipped because their bank reference was imported before."
          },
          "matched": {
            "type": "integer",
            "title": "Matched",
            "description": "Number of imported lines the automatic matcher settled."
          },
          "unmatched": {
            "type": "integer",
            "title": "Unmatched",
            "description": "Number of imported lines left for a person or agent (`imported - matched`)."
          }
        },
        "type": "object",
        "required": [
          "statement_id",
          "statement_ref",
          "imported",
          "duplicates",
          "matched",
          "unmatched"
        ],
        "title": "ImportResult"
      },
      "ImportSummary": {
        "properties": {
          "created": {
            "type": "integer",
            "title": "Created",
            "description": "Records created: customers, vendors, accounts, or documents (open items); 1 for the opening entry."
          },
          "waiting_for_activation": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Waiting For Activation",
            "description": "Vendors (and customers, if the approval policy says so) created as drafts that a second person must activate (`GET /v1/approvals`) before their documents can be posted or paid; null for other imports."
          },
          "posted": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posted",
            "description": "Open items posted (their opening entries are in the ledger); null for other imports."
          },
          "waiting_for_approval": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Waiting For Approval",
            "description": "Entries the approval policy sent to a second person instead of posting; null for other imports."
          },
          "total_debit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Debit",
            "description": "`opening_balances`: the debits of the file in the entity's currency."
          },
          "total_credit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total Credit",
            "description": "`opening_balances`: the credits of the file in the entity's currency."
          },
          "clearing_difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Clearing Difference",
            "description": "`opening_balances`: debits less credits of the file, which the entry books to the opening balance clearing account (the receivables and payables of the trial balance are imported as open items, so they are not in the file's entry); 0 when the file balances by itself."
          },
          "amounts_by_currency": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string"
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amounts By Currency",
            "description": "Open items: the total imported per currency (credit notes count negative)."
          },
          "clearing_balance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Clearing Balance",
            "description": "The balance of the entity's opening balance clearing account after the import (debits less credits), in its functional currency. After the opening balances and both open item lists are imported it is 0 when they agree."
          },
          "entry": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ImportEntry"
              },
              {
                "type": "null"
              }
            ],
            "description": "`opening_balances`: the opening entry; null otherwise."
          }
        },
        "type": "object",
        "required": [
          "created"
        ],
        "title": "ImportSummary",
        "description": "What the import created (or, in a dry run, would create)."
      },
      "InboundInput": {
        "properties": {
          "to": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 50,
            "minItems": 1,
            "title": "To",
            "description": "The addresses it was sent to (To and Cc)."
          },
          "from_address": {
            "type": "string",
            "title": "From Address",
            "description": "The sender's address."
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "From Name",
            "description": "The sender's name."
          },
          "subject": {
            "type": "string",
            "maxLength": 1000,
            "title": "Subject",
            "description": "The subject.",
            "default": ""
          },
          "body": {
            "type": "string",
            "maxLength": 100000,
            "title": "Body",
            "description": "The text of the message."
          },
          "message_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Message Id",
            "description": "Its Message-ID: handed over twice, kept once."
          },
          "in_reply_to": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "In Reply To",
            "description": "In-Reply-To."
          },
          "references": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 100,
            "title": "References",
            "description": "The Message-IDs of References."
          },
          "received_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Received At",
            "description": "When it arrived."
          },
          "auto": {
            "type": "boolean",
            "title": "Auto",
            "description": "An automatic message (out of office, a bounce): kept on its case, but it opens no case and reopens none.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "to",
          "from_address",
          "body"
        ],
        "title": "InboundInput",
        "examples": [
          {
            "body": "Hello, our order 2026-0107 has not arrived yet.",
            "from_address": "anna.muster@kunde.example",
            "from_name": "Anna Muster",
            "message_id": "<CAF1234@mail.kunde.example>",
            "subject": "Delivery missing",
            "to": [
              "support@example.ch"
            ]
          }
        ]
      },
      "InboundOut": {
        "properties": {
          "case": {
            "$ref": "#/components/schemas/CaseOut",
            "description": "The case the message is on."
          },
          "message_id": {
            "type": "string",
            "format": "uuid",
            "title": "Message Id",
            "description": "Id of the message on the case."
          },
          "created": {
            "type": "boolean",
            "title": "Created",
            "description": "A new case was opened."
          },
          "duplicate": {
            "type": "boolean",
            "title": "Duplicate",
            "description": "The message was there already: nothing changed."
          }
        },
        "type": "object",
        "required": [
          "case",
          "message_id",
          "created",
          "duplicate"
        ],
        "title": "InboundOut"
      },
      "IndustryModuleOut": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The feature module's name, e.g. `hospitality`."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Its title, e.g. `Hospitality`."
          }
        },
        "type": "object",
        "required": [
          "name",
          "title"
        ],
        "title": "IndustryModuleOut"
      },
      "IndustryOut": {
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "ecommerce",
              "general",
              "hospitality",
              "manufacturing",
              "retail",
              "services",
              "trade"
            ],
            "title": "Key",
            "description": "The industry's key, the `industry` of a company."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name in English; the app shows its own translation."
          },
          "status": {
            "type": "string",
            "enum": [
              "partial",
              "planned",
              "ready"
            ],
            "title": "Status",
            "description": "How far it is built: `ready` (its own screens exist), `partial` (the general screens serve it, some of its own are missing) or `planned` (nothing of its own yet: the general layout)."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "What the product does for it, and what it does not yet."
          },
          "modules": {
            "items": {
              "$ref": "#/components/schemas/IndustryModuleOut"
            },
            "type": "array",
            "title": "Modules",
            "description": "The feature modules that serve it, whose screens come first in it."
          }
        },
        "type": "object",
        "required": [
          "key",
          "name",
          "status",
          "summary",
          "modules"
        ],
        "title": "IndustryOut"
      },
      "IngestRunOut": {
        "properties": {
          "connector": {
            "type": "string",
            "title": "Connector",
            "description": "Name of the connector that ran."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "title": "Started At",
            "description": "When the run started (ISO 8601, UTC)."
          },
          "finished_at": {
            "type": "string",
            "format": "date-time",
            "title": "Finished At",
            "description": "When it finished (ISO 8601, UTC)."
          },
          "ok": {
            "type": "boolean",
            "title": "Ok",
            "description": "True when the run succeeded."
          },
          "fetched": {
            "type": "integer",
            "title": "Fetched",
            "description": "Number of records fetched.",
            "default": 0
          },
          "stored": {
            "type": "integer",
            "title": "Stored",
            "description": "Number of records stored.",
            "default": 0
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "The error message when the run failed; null if it succeeded."
          },
          "last_success_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Success At",
            "description": "When the connector last succeeded (ISO 8601, UTC); null if never."
          }
        },
        "type": "object",
        "required": [
          "connector",
          "started_at",
          "finished_at",
          "ok"
        ],
        "title": "IngestRunOut"
      },
      "Insights": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; amounts are in it."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range (ISO 8601)."
          },
          "comparison": {
            "$ref": "#/components/schemas/ComparisonRange",
            "description": "The range the figures are compared with."
          },
          "materiality": {
            "type": "string",
            "title": "Materiality",
            "description": "The threshold used, functional currency."
          },
          "flagged_total": {
            "type": "integer",
            "title": "Flagged Total",
            "description": "How many accounts are flagged; `flux` holds the largest `limit`."
          },
          "flux": {
            "items": {
              "$ref": "#/components/schemas/FluxInsight"
            },
            "type": "array",
            "title": "Flux",
            "description": "The flagged accounts, the largest variance first, each with a sentence."
          },
          "unusual_total": {
            "type": "integer",
            "title": "Unusual Total",
            "description": "How many entries of the range carry a risk flag; `unusual` holds the largest `limit`."
          },
          "unusual": {
            "items": {
              "$ref": "#/components/schemas/UnusualEntry"
            },
            "type": "array",
            "title": "Unusual",
            "description": "Entries with risk flags (manual, agent, round, large, weekend, reversal), largest amount first."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "start",
          "end",
          "comparison",
          "materiality",
          "flagged_total",
          "flux",
          "unusual_total",
          "unusual"
        ],
        "title": "Insights"
      },
      "InterestInput": {
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "title": "Through",
            "description": "Accrue the interest up to and including this day, from the day after the last accrual (or from the first drawdown)."
          }
        },
        "type": "object",
        "required": [
          "through"
        ],
        "title": "InterestInput",
        "examples": [
          {
            "through": "2026-10-31"
          }
        ]
      },
      "InterestPart": {
        "properties": {
          "interest_rate": {
            "type": "string",
            "title": "Interest Rate",
            "description": "The yearly rate in percent of these days."
          },
          "interest_from": {
            "type": "string",
            "format": "date",
            "title": "Interest From",
            "description": "The part runs from the day after this one."
          },
          "interest_until": {
            "type": "string",
            "format": "date",
            "title": "Interest Until",
            "description": "The last day of the part."
          },
          "interest": {
            "type": "string",
            "title": "Interest",
            "description": "The interest of these days, in the invoice's currency."
          }
        },
        "type": "object",
        "required": [
          "interest_rate",
          "interest_from",
          "interest_until",
          "interest"
        ],
        "title": "InterestPart",
        "description": "Part of an invoice's default interest that one rate covers, when the rate changed in the\nspan: a German company's default rates follow the base rate, which changes on 1 January and\n1 July, and the days on each side of the change are charged at their own rate."
      },
      "InviteInput": {
        "properties": {
          "email": {
            "type": "string",
            "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
            "title": "Email",
            "description": "The person's email address; they sign in with the Google account of this address, or, without one, with this address and a password. Stored in lower case."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The person's name, shown in the UI; filled from Google at first sign-in when omitted."
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "accountant",
                  "admin",
                  "auditor",
                  "controller",
                  "viewer"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Preset scopes; or pass scopes."
          },
          "scopes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scopes",
            "description": "Explicit scopes (`read`, `draft`, `post`, `approve`, `admin`, `audit`). When given and not empty it wins over `role`."
          },
          "access_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Until",
            "description": "When the person's access ends (ISO 8601; without a time zone, UTC): in the future, at most two years ahead. Required for an external auditor (the `auditor` role, or `read` and `audit` without a right that changes anything): every request they make is then recorded in the access log (`GET /v1/access-log`)."
          },
          "approver": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ApproverDeclaration"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who the person is, declared by the administrator: required when the access lets the person approve (`controller`, `admin`, or the `approve` scope) (422 `approver_declaration_missing`); 409 `approver_same_person` for an address or name that is plainly the administrator's own. Recorded in the audit trail and shown in the approver register (`GET /v1/approvers`)."
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "InviteInput",
        "examples": [
          {
            "email": "anna.keller@example.com",
            "name": "Anna Keller",
            "role": "accountant"
          },
          {
            "access_until": "2027-03-31T23:59:59Z",
            "email": "pruefer@audit-firm.example",
            "name": "Lena Brunner",
            "role": "auditor"
          }
        ]
      },
      "InvitedUser": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the user."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The sign-in address, lower case."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Display name; null until set."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The scopes the user holds: some of `read`, `draft`, `post`, `approve`, `admin`, `audit`."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`invited` (never signed in), `active` or `disabled`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the user was invited (ISO 8601, UTC)."
          },
          "last_login_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Login At",
            "description": "The last sign-in; null if never."
          },
          "locale": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Locale",
            "description": "The user's UI language (`en`, `de-CH`, `fr-CH`, `it-CH`, `sv-SE`); null follows the browser."
          },
          "access_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Until",
            "description": "When the person's access ends (ISO 8601, UTC): from then on they cannot sign in and their sessions stop. Null for no end. An external auditor always has one."
          },
          "password_email_sent": {
            "type": "boolean",
            "title": "Password Email Sent",
            "description": "True when Google e-mailed the person the link that sets their password (false when password sign-in is not configured, or for an address of a Google Workspace domain, whose people sign in with Google)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "email",
          "name",
          "scopes",
          "status",
          "created_at",
          "last_login_at",
          "password_email_sent"
        ],
        "title": "InvitedUser"
      },
      "Invoice": {
        "properties": {
          "syntax": {
            "type": "string",
            "enum": [
              "CII",
              "UBL"
            ],
            "title": "Syntax",
            "description": "The XML syntax the invoice came in: UBL or CII."
          },
          "specification_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Specification Id",
            "description": "BT-24"
          },
          "business_process": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Business Process",
            "description": "BT-23"
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "BT-1"
          },
          "issue_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Issue Date",
            "description": "BT-2"
          },
          "type_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Type Code",
            "description": "BT-3 UNTDID 1001"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "BT-5"
          },
          "tax_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Currency",
            "description": "BT-6"
          },
          "tax_point_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Point Date",
            "description": "BT-7"
          },
          "tax_point_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Point Code",
            "description": "BT-8"
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "BT-9"
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "BT-10 (e.g. Leitweg-ID)"
          },
          "project_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Reference",
            "description": "BT-11"
          },
          "contract_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contract Reference",
            "description": "BT-12"
          },
          "order_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Reference",
            "description": "BT-13"
          },
          "sales_order_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Order Reference",
            "description": "BT-14"
          },
          "receiving_advice": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receiving Advice",
            "description": "BT-15"
          },
          "despatch_advice": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Despatch Advice",
            "description": "BT-16"
          },
          "tender_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tender Reference",
            "description": "BT-17"
          },
          "invoiced_object": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Invoiced Object",
            "description": "BT-18"
          },
          "accounting_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accounting Reference",
            "description": "BT-19"
          },
          "payment_terms": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms",
            "description": "BT-20"
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "BT-22, prefixed #code# with a subject code (BT-21)"
          },
          "preceding_invoices": {
            "items": {
              "$ref": "#/components/schemas/PrecedingInvoice"
            },
            "type": "array",
            "title": "Preceding Invoices",
            "description": "BG-3"
          },
          "seller": {
            "$ref": "#/components/schemas/Party",
            "description": "BG-4"
          },
          "buyer": {
            "$ref": "#/components/schemas/Party",
            "description": "BG-7"
          },
          "payee": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Party"
              },
              {
                "type": "null"
              }
            ],
            "description": "BG-10"
          },
          "tax_representative": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Party"
              },
              {
                "type": "null"
              }
            ],
            "description": "BG-11"
          },
          "delivery_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Date",
            "description": "BT-72"
          },
          "period_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period Start",
            "description": "BT-73"
          },
          "period_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period End",
            "description": "BT-74"
          },
          "deliver_to": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PostalAddress"
              },
              {
                "type": "null"
              }
            ],
            "description": "BG-15"
          },
          "payment_means": {
            "items": {
              "$ref": "#/components/schemas/PaymentMeans"
            },
            "type": "array",
            "title": "Payment Means",
            "description": "BG-16"
          },
          "remittance_information": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remittance Information",
            "description": "BT-83"
          },
          "creditor_reference_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditor Reference Id",
            "description": "BT-90"
          },
          "allowances_charges": {
            "items": {
              "$ref": "#/components/schemas/AllowanceCharge"
            },
            "type": "array",
            "title": "Allowances Charges",
            "description": "BG-20 / BG-21"
          },
          "totals": {
            "$ref": "#/components/schemas/Totals"
          },
          "vat_breakdown": {
            "items": {
              "$ref": "#/components/schemas/VatBreakdown"
            },
            "type": "array",
            "title": "Vat Breakdown",
            "description": "BG-23"
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/Line"
            },
            "type": "array",
            "title": "Lines",
            "description": "BG-25"
          },
          "attachments": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Attachments",
            "description": "BG-24 supporting document references (BT-122)"
          }
        },
        "type": "object",
        "required": [
          "syntax"
        ],
        "title": "Invoice",
        "description": "An invoice (or credit note) in EN 16931 terms, whatever syntax it came in."
      },
      "InvoiceContentOut": {
        "properties": {
          "country": {
            "type": "string",
            "title": "Country",
            "description": "The entity's country, whose rules apply."
          },
          "seller": {
            "items": {
              "$ref": "#/components/schemas/InvoiceField"
            },
            "type": "array",
            "title": "Seller",
            "description": "Fields of the company profile."
          },
          "buyer": {
            "items": {
              "$ref": "#/components/schemas/InvoiceField"
            },
            "type": "array",
            "title": "Buyer",
            "description": "Fields of each customer's record."
          }
        },
        "type": "object",
        "required": [
          "country",
          "seller",
          "buyer"
        ],
        "title": "InvoiceContentOut",
        "description": "What the law requires an invoice of this entity to show about its seller and customers."
      },
      "InvoiceField": {
        "properties": {
          "field": {
            "type": "string",
            "enum": [
              "name",
              "postal_code",
              "street",
              "tax_id",
              "town",
              "vat_designation",
              "vat_number"
            ],
            "title": "Field",
            "description": "The field, as in `missing_content`: `name`, `street`, `postal_code`, `town`, `vat_number`, `tax_id` (the seller's USt-IdNr or Steuernummer) or `vat_designation` (a Swiss UID with MWST, TVA or IVA)."
          },
          "basis": {
            "type": "string",
            "title": "Basis",
            "description": "The legal basis that makes it mandatory."
          },
          "always": {
            "type": "boolean",
            "title": "Always",
            "description": "True: every invoice needs it. False: only some (e.g. an intra-community supply needs the customer's VAT number)."
          }
        },
        "type": "object",
        "required": [
          "field",
          "basis",
          "always"
        ],
        "title": "InvoiceField",
        "description": "One field of a seller's or customer's record that an invoice of this entity must show."
      },
      "InvoiceLineInput": {
        "properties": {
          "line_no": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Line No",
            "description": "Number of the order line."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Quantity",
            "description": "Quantity to invoice now."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "quantity"
        ],
        "title": "InvoiceLineInput"
      },
      "InvoiceOrderInput": {
        "properties": {
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "Day of the invoice; default today."
          },
          "supply_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Supply Date",
            "description": "The date of supply, e.g. the day the goods were delivered; default: the day of the invoice. Where the law of the company's country says so, it decides the VAT period (see `supply_date` of `POST /v1/documents`)."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/InvoiceLineInput"
                },
                "type": "array",
                "maxItems": 200,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "What to invoice per order line; omitted: everything left to invoice."
          }
        },
        "type": "object",
        "title": "InvoiceOrderInput",
        "examples": [
          {},
          {
            "document_date": "2026-10-31",
            "lines": [
              {
                "line_no": 1,
                "quantity": "4"
              }
            ]
          }
        ]
      },
      "Issue": {
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "blocker",
              "info",
              "warning"
            ],
            "title": "Severity",
            "description": "`blocker` (do not lock the period), `warning` or `info`."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "A short title."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "What was found."
          },
          "references": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "References",
            "description": "Entry numbers, document numbers or account codes."
          }
        },
        "type": "object",
        "required": [
          "severity",
          "title",
          "detail"
        ],
        "title": "Issue"
      },
      "ItemRow": {
        "properties": {
          "link_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Link Id",
            "description": "The link; null for a document without one."
          },
          "origin": {
            "$ref": "#/components/schemas/DocumentRef",
            "description": "The origin document, or the unlinked document."
          },
          "counter": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DocumentRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The counterpart, when there is one."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Document currency."
          },
          "origin_open": {
            "type": "string",
            "title": "Origin Open",
            "description": "Open amount of the origin as of the day (posted)."
          },
          "counter_open": {
            "type": "string",
            "title": "Counter Open",
            "description": "Open amount of the counterpart; 0 until posted."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`origin_open` less `counter_open` (for an unlinked bill the minus of its open amount); zero when both sides agree."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "amount_differs",
                  "cutoff",
                  "loan_movement_missing",
                  "mirror_draft",
                  "mirror_missing",
                  "mirror_pending_approval",
                  "mirror_rejected",
                  "payment_in_transit",
                  "unlinked_document"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why they differ: a timing reason (`mirror_missing`, `mirror_draft`, `mirror_pending_approval`, `payment_in_transit`, `cutoff`) is explained and the counterpart's to resolve; `mirror_rejected`, `unlinked_document` and `amount_differs` are unexplained. Null when `difference` is zero."
          },
          "explained": {
            "type": "boolean",
            "title": "Explained",
            "description": "True when the difference is wholly a timing reason (or zero)."
          }
        },
        "type": "object",
        "required": [
          "link_id",
          "origin",
          "counter",
          "currency",
          "origin_open",
          "counter_open",
          "difference",
          "reason",
          "explained"
        ],
        "title": "ItemRow",
        "description": "One link, or one group document without a link, and what its two sides hold."
      },
      "JobLogEntry": {
        "properties": {
          "step": {
            "type": "string",
            "enum": [
              "bank_matching",
              "checklist",
              "close_review",
              "deferred_tax",
              "depreciation",
              "forecast_roll",
              "fx_revaluation",
              "recurring_invoices"
            ],
            "title": "Step",
            "description": "The step the job ran."
          },
          "run_date": {
            "type": "string",
            "format": "date",
            "title": "Run Date",
            "description": "The day it ran for: today where the entity is."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "done",
              "failed"
            ],
            "title": "Outcome",
            "description": "`done`, or `failed` (the next run tries again)."
          },
          "attempts": {
            "type": "integer",
            "title": "Attempts",
            "description": "How many times it was tried that day."
          },
          "summary": {
            "additionalProperties": true,
            "type": "object",
            "title": "Summary",
            "description": "What it made: for `recurring_invoices` `made`, `failed` and `more_due`; for `checklist` `ready`, the `failing` check ids and the `checks` counted by status."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why it failed."
          },
          "finished_at": {
            "type": "string",
            "format": "date-time",
            "title": "Finished At",
            "description": "When the last attempt ended (UTC)."
          }
        },
        "type": "object",
        "required": [
          "step",
          "run_date",
          "outcome",
          "attempts",
          "summary",
          "error",
          "finished_at"
        ],
        "title": "JobLogEntry"
      },
      "JournalEntryOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the entry; the `{entry_id}` of other operations."
          },
          "entity_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entity Id",
            "description": "Id (uuid) of the entity."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Entry number such as `2026-000042`, assigned when it is posted; null before."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval` (waits for a second person), `posted` (final) or `rejected`."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "The posting date (ISO 8601)."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the entry is for."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "`manual`, or the subledger or process that created it: `ar`, `ap`, `fa`, `bank`, `fx`, `close` (the year-end closing entry), `appropriation` (a resolution on the result), `ic` (intercompany), `rev` (revenue recognition) or `opening` (a data import's opening entry)."
          },
          "source_ref": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Ref",
            "description": "The caller's own reference; null if none."
          },
          "reverses_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reverses Id",
            "description": "For a reversal, the id of the entry it reverses; else null."
          },
          "reversed_by_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversed By Id",
            "description": "Once reversed, the id of the reversal entry; else null."
          },
          "auto_reverse_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auto Reverse On",
            "description": "The reversal is posted on this date when the entry posts."
          },
          "adjustment_period": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Adjustment Period",
            "description": "The adjustment period the entry is in (e.g. 13); null in a regular period."
          },
          "provenance": {
            "additionalProperties": true,
            "type": "object",
            "title": "Provenance",
            "description": "Free-form JSON recording where the entry came from, e.g. the FX rates used or the document it was built from."
          },
          "hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Hash",
            "description": "SHA-256 hash of the posted entry's content and `prev_hash`; null before posting."
          },
          "prev_hash": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Prev Hash",
            "description": "The `hash` of the previous posted entry of the entity (the hash chain); null for the first and before posting."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "The actor, as stored in the audit trail: an object with `type` (`human`, `agent` or `system`), `id` (`user:<id>`, `key:<prefix>` or `system:<name>`) and `name`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the entry was created (ISO 8601, UTC)."
          },
          "posted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posted By",
            "description": "The actor that posted it, as `created_by`; null before posting."
          },
          "posted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posted At",
            "description": "When it was posted (ISO 8601, UTC); null before."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/JournalLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines of the entry."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity_id",
          "number",
          "status",
          "entry_date",
          "description",
          "source",
          "source_ref",
          "reverses_id",
          "reversed_by_id",
          "provenance",
          "hash",
          "prev_hash",
          "created_by",
          "created_at",
          "posted_by",
          "posted_at"
        ],
        "title": "JournalEntryOut"
      },
      "JournalLineOut": {
        "properties": {
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Position of the line in the entry, from 1."
          },
          "account_id": {
            "type": "string",
            "format": "uuid",
            "title": "Account Id",
            "description": "Id (uuid) of the account (`GET /v1/entities/{entity}/accounts`)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text of the line; null if none."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the line."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Debit amount in the line's currency; 0 on a credit line."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Credit amount in the line's currency; 0 on a debit line."
          },
          "fx_rate": {
            "type": "string",
            "title": "Fx Rate",
            "description": "Units of the entity's functional currency per unit of `currency`; 1 when the line is in the functional currency."
          },
          "functional_debit": {
            "type": "string",
            "title": "Functional Debit",
            "description": "The debit in the entity's functional currency."
          },
          "functional_credit": {
            "type": "string",
            "title": "Functional Credit",
            "description": "The credit in the entity's functional currency."
          },
          "tax_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Code",
            "description": "VAT treatment code of the line; null if none."
          },
          "tax": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax",
            "description": "VAT tag the VAT report reads (`kind` `base` or `tax`, direction, jurisdiction, treatment, rate); `kind` `foreign_vat` on a bill's lines that book the net amount and the foreign VAT the company cannot reclaim as cost, and `non_deductible` on the line that books the part of a bill line's input VAT that is not deductible as cost (`recovery_percent`), which no VAT report reads; null on lines without VAT."
          },
          "fx": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fx",
            "description": "Where the exchange rate came from (source, rate, fixing date); null in the functional currency."
          },
          "counterparty_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Type",
            "description": "`customer` or `vendor`; null if none."
          },
          "counterparty_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Id",
            "description": "Id (uuid) of the customer or vendor; null if none."
          },
          "subledger_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subledger Type",
            "description": "Kind of subledger record the line belongs to; null for manual lines."
          },
          "subledger_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subledger Id",
            "description": "Id (uuid) of that subledger record; null for manual lines."
          },
          "dimensions": {
            "additionalProperties": true,
            "type": "object",
            "title": "Dimensions",
            "description": "The line's cost centre, profit centre, project ...: dimension code to value code."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "account_id",
          "description",
          "currency",
          "debit",
          "credit",
          "fx_rate",
          "functional_debit",
          "functional_credit",
          "tax_code",
          "tax",
          "fx",
          "counterparty_type",
          "counterparty_id",
          "subledger_type",
          "subledger_id",
          "dimensions"
        ],
        "title": "JournalLineOut"
      },
      "KeyInfo": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the key."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The label given when the key was issued."
          },
          "prefix": {
            "type": "string",
            "title": "Prefix",
            "description": "Identifies the key; audit events name it as key:<prefix>."
          },
          "actor_type": {
            "type": "string",
            "title": "Actor Type",
            "description": "`human` or `agent`."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The scopes the key holds: some of `read`, `draft`, `post`, `approve`, `admin`, `audit`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the key was issued (ISO 8601, UTC)."
          },
          "last_used_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Used At",
            "description": "When a request last used the key; null if never."
          },
          "revoked_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revoked At",
            "description": "When the key was revoked; null while active."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "revoked"
            ],
            "title": "Status",
            "description": "`active` or `revoked`."
          },
          "bound_to": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bound To",
            "description": "The person the key acts for: the actor id of a user (`user:<id>`). Four eyes and segregation of duties compare people, and a key counts as the person who created it, so a key a signed-in person created is bound to that person. Null when it belongs to no known person (the organization's first key, issued by the system, and every key created with it): it can request but never approve, activate, release or finalise."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "prefix",
          "actor_type",
          "scopes",
          "created_at",
          "last_used_at",
          "revoked_at",
          "status"
        ],
        "title": "KeyInfo",
        "description": "An API key without its secret: neither the key nor its hash ever leaves the server."
      },
      "KeyOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the key, for `GET` and `DELETE /v1/api-keys/{key_id}`."
          },
          "key": {
            "type": "string",
            "title": "Key",
            "description": "Shown once. Store it securely; only its hash is kept."
          },
          "actor_type": {
            "type": "string",
            "title": "Actor Type",
            "description": "`human` or `agent`."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The scopes the key holds."
          },
          "bound_to": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bound To",
            "description": "The person the key acts for: the actor id of a user (`user:<id>`). Four eyes and segregation of duties compare people, and a key counts as the person who created it, so a key a signed-in person created is bound to that person. Null when it belongs to no known person (the organization's first key, issued by the system, and every key created with it): it can request but never approve, activate, release or finalise."
          }
        },
        "type": "object",
        "required": [
          "id",
          "key",
          "actor_type",
          "scopes"
        ],
        "title": "KeyOut"
      },
      "KeyRequest": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "A label for the key, e.g. `bookkeeping agent`; shown in listings."
          },
          "actor_type": {
            "type": "string",
            "enum": [
              "agent",
              "human"
            ],
            "title": "Actor Type",
            "description": "human or agent; system actors exist only inside the server (CLI, jobs)."
          },
          "scopes": {
            "items": {
              "type": "string",
              "enum": [
                "admin",
                "approve",
                "audit",
                "draft",
                "post",
                "read"
              ]
            },
            "type": "array",
            "title": "Scopes",
            "description": "What the key may do: `read`, `draft`, `post`, `approve`, `admin`, `audit` (the archive export). `admin` includes the others; agent keys may not hold `approve`, `admin` or `audit`."
          }
        },
        "type": "object",
        "required": [
          "name",
          "actor_type",
          "scopes"
        ],
        "title": "KeyRequest",
        "examples": [
          {
            "actor_type": "agent",
            "name": "bookkeeping agent",
            "scopes": [
              "read",
              "draft",
              "post"
            ]
          }
        ]
      },
      "Kpi": {
        "properties": {
          "key": {
            "type": "string",
            "enum": [
              "cash",
              "cost_of_sales",
              "dpo",
              "dso",
              "expenses",
              "gross_margin_pct",
              "net_income",
              "operating_expenses",
              "payables",
              "payables_aging",
              "receivables",
              "receivables_aging",
              "revenue",
              "unearned_revenue",
              "working_capital"
            ],
            "title": "Key",
            "description": "The metric (`GET .../analytics/series?metric=` takes it)."
          },
          "unit": {
            "type": "string",
            "enum": [
              "amount",
              "days",
              "percent"
            ],
            "title": "Unit",
            "description": "`amount`, `percent` or `days`."
          },
          "value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value",
            "description": "A flow: the total of the range; a stock: the balance on its last day; a ratio: computed over the range. Null where a ratio has no denominator."
          },
          "comparison": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comparison",
            "description": "The same figure for the comparison range."
          },
          "delta": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delta",
            "description": "`value` less `comparison` (percentage points for a percent, days for days); null if either is missing."
          },
          "delta_pct": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delta Pct",
            "description": "`delta` as a percentage of the absolute comparison, one decimal; null for percent and days, and when the comparison is zero."
          },
          "direction": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "down",
                  "flat",
                  "up"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Direction",
            "description": "The sign of `delta`; null if there is none."
          },
          "favourable": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Favourable",
            "description": "Whether the change is good news (revenue up, expenses down); null for a flat change and for metrics where neither direction is better."
          },
          "spark": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "array",
            "title": "Spark",
            "description": "The metric per period over the range, in the order of `periods`."
          }
        },
        "type": "object",
        "required": [
          "key",
          "unit",
          "value",
          "comparison",
          "delta",
          "delta_pct",
          "direction",
          "favourable",
          "spark"
        ],
        "title": "Kpi"
      },
      "Kpis": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; amounts are in it."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range (ISO 8601)."
          },
          "comparison": {
            "$ref": "#/components/schemas/ComparisonRange",
            "description": "The range the figures are compared with."
          },
          "granularity": {
            "type": "string",
            "enum": [
              "month",
              "quarter",
              "year"
            ],
            "title": "Granularity",
            "description": "The size of the periods of `spark`."
          },
          "periods": {
            "items": {
              "$ref": "#/components/schemas/SeriesPeriod"
            },
            "type": "array",
            "title": "Periods",
            "description": "The periods of every `spark`."
          },
          "kpis": {
            "items": {
              "$ref": "#/components/schemas/Kpi"
            },
            "type": "array",
            "title": "Kpis",
            "description": "Revenue, gross margin, operating expenses, net income, cash, receivables, payables, DSO, DPO and working capital, in that order."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "start",
          "end",
          "comparison",
          "granularity",
          "periods",
          "kpis"
        ],
        "title": "Kpis"
      },
      "LeadConvert": {
        "properties": {
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the existing customer the person works for; or `customer`."
          },
          "customer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LeadCustomer"
              },
              {
                "type": "null"
              }
            ],
            "description": "The new customer to create; or `party`."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "An existing contact of `party` who is this person; omitted: the lead becomes a new contact of the customer."
          },
          "create_deal": {
            "type": "boolean",
            "title": "Create Deal",
            "description": "Open a deal with the customer.",
            "default": true
          },
          "deal_title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Deal Title",
            "description": "The deal; omitted: the company."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "The deal's expected net value.",
            "default": "0"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The deal's currency; omitted: the customer's."
          },
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "negotiation",
              "proposal",
              "qualified"
            ],
            "title": "Stage",
            "description": "The open stage the deal starts at (a converted lead is qualified).",
            "default": "qualified"
          },
          "expected_close": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Close",
            "description": "When it should close."
          }
        },
        "type": "object",
        "title": "LeadConvert",
        "examples": [
          {
            "amount": "15000.00",
            "customer": {
              "code": "C-BEISPIEL",
              "country": "DE",
              "currency": "EUR"
            },
            "deal_title": "Platform for 25 seats",
            "expected_close": "2026-12-15"
          },
          {
            "create_deal": false,
            "party": "C-CH"
          }
        ]
      },
      "LeadCustomer": {
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Its code; left out, the company's next customer number (`C-00001`)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Legal name; omitted: the lead's company."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Country; omitted: the lead's, else the company's."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Currency of its documents; omitted: its country's when the company has exchange rates for it, else the company's functional currency."
          },
          "business": {
            "type": "boolean",
            "title": "Business",
            "description": "`false` for a private person (B2C).",
            "default": true
          }
        },
        "type": "object",
        "title": "LeadCustomer",
        "description": "The customer converting the lead creates (master data, with the customer controls)."
      },
      "LeadFormInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company whose leads it creates."
          },
          "name": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Name",
            "description": "What the form is, e.g. `Contact us`."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who the leads go to (`GET /v1/people`); omitted: nobody yet."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of its own page.",
            "default": "en"
          },
          "allowed_origins": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Allowed Origins",
            "description": "The websites it may be sent from, e.g. `https://www.example.ch`; empty: any. A browser names its page's site, so a copy of the form on another site is refused."
          },
          "thank_you": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Thank You",
            "description": "What its page says after sending."
          },
          "redirect_url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "pattern": "^https://"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redirect Url",
            "description": "A page of your own (https) to send people to after a form of your own website was sent; omitted: the thank-you page."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name"
        ],
        "title": "LeadFormInput",
        "examples": [
          {
            "allowed_origins": [
              "https://www.example.ch"
            ],
            "entity": "CH01",
            "language": "de",
            "name": "Contact us",
            "owner_user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
            "thank_you": "Danke! Wir melden uns innert eines Arbeitstages."
          }
        ]
      },
      "LeadFormOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Form id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Company code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What the form is."
          },
          "key": {
            "type": "string",
            "title": "Key",
            "description": "Its public key: it goes into your website. A new key (`POST /v1/lead-forms/{form_id}/new-key`) stops the old one."
          },
          "page_path": {
            "type": "string",
            "title": "Page Path",
            "description": "Its own page on this server (to link to or embed in an iframe); `POST` to the same path sends a lead."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether it takes leads."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who its leads go to."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "Its page's language."
          },
          "allowed_origins": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Allowed Origins",
            "description": "The websites it may be sent from; empty: any."
          },
          "thank_you": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Thank You",
            "description": "What its page says after sending."
          },
          "redirect_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redirect Url",
            "description": "Where people go after sending your own form."
          },
          "leads": {
            "type": "integer",
            "title": "Leads",
            "description": "How many leads it created."
          },
          "last_lead_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Lead At",
            "description": "When it created the last one (UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who set it up."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "name",
          "key",
          "page_path",
          "active",
          "owner",
          "language",
          "allowed_origins",
          "thank_you",
          "redirect_url",
          "leads",
          "last_lead_at",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "LeadFormOut",
        "examples": [
          {
            "active": true,
            "allowed_origins": [
              "https://www.example.ch"
            ],
            "created_at": "2026-10-20T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "entity": "CH01",
            "id": "9f2a3b4c-5d6e-4f7a-8b8c-9d0e1f2a3b4c",
            "key": "lf_0b9c4a2e7d1f4e3a9c5b6d7e8f9a0b1c_Qm3xV7pL2sK9tR4wY8zN1a",
            "language": "de",
            "last_lead_at": "2026-10-23T09:12:00Z",
            "leads": 12,
            "name": "Contact us",
            "owner": {
              "email": "alice@example.com",
              "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "name": "Alice"
            },
            "page_path": "/forms/leads/lf_0b9c4a2e7d1f4e3a9c5b6d7e8f9a0b1c_Qm3xV7pL2sK9tR4wY8zN1a"
          }
        ]
      },
      "LeadFormUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New name."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "`false` switches it off."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "string",
                "const": ""
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who the leads go to; `\"\"`: nobody."
          },
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "sv"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Its page's language."
          },
          "allowed_origins": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 20
              },
              {
                "type": "null"
              }
            ],
            "title": "Allowed Origins",
            "description": "The websites it may be sent from; `[]`: any."
          },
          "thank_you": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Thank You",
            "description": "`\"\"` clears."
          },
          "redirect_url": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "pattern": "^(https://.*)?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redirect Url",
            "description": "`\"\"` clears."
          }
        },
        "type": "object",
        "title": "LeadFormUpdate",
        "examples": [
          {
            "allowed_origins": [
              "https://www.example.ch"
            ],
            "language": "fr"
          }
        ]
      },
      "LeadInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company whose lead it is."
          },
          "first_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name",
            "description": "First name."
          },
          "last_name": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Last Name",
            "description": "Last name."
          },
          "company": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Company",
            "description": "Their company."
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Their job title."
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Phone number."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Their country (ISO 3166-1)."
          },
          "message": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 5000
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "What they asked."
          },
          "source": {
            "type": "string",
            "enum": [
              "advertising",
              "email",
              "event",
              "hubspot",
              "import",
              "other",
              "partner",
              "phone",
              "referral",
              "web_form"
            ],
            "title": "Source",
            "description": "Where the lead came from: `web_form`, `phone`, `email`, `referral`, `partner`, `event`, `advertising`, `import`, `hubspot`, `other`.",
            "default": "other"
          },
          "source_detail": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Detail",
            "description": "The campaign, event or list, e.g. a fair."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who works on the lead (`GET /v1/people`); omitted: nobody yet."
          },
          "email_opt_out": {
            "type": "boolean",
            "title": "Email Opt Out",
            "description": "They asked not to get sales or marketing e-mails.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "entity",
          "last_name"
        ],
        "title": "LeadInput",
        "examples": [
          {
            "company": "Beispiel GmbH",
            "country": "DE",
            "email": "eva@beispiel.example",
            "entity": "CH01",
            "first_name": "Eva",
            "last_name": "Beispiel",
            "owner_user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
            "phone": "+49 30 1234567",
            "role": "Head of Finance",
            "source": "event",
            "source_detail": "Swiss Finance Day 2026"
          }
        ]
      },
      "LeadOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Lead id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Company code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "`LEAD-000001`, per company."
          },
          "status": {
            "type": "string",
            "enum": [
              "converted",
              "disqualified",
              "new",
              "working"
            ],
            "title": "Status",
            "description": "`new` (nobody has talked to them yet), `working` (someone is on it), `disqualified` (not a fit, with a reason) or `converted` (now a customer, a contact and a deal)."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "First and last name; `\"\"` once erased."
          },
          "first_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name",
            "description": "First name."
          },
          "last_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name",
            "description": "Last name."
          },
          "company": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Company",
            "description": "Their company."
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Their job title."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Phone number."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "Their country."
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "What they asked."
          },
          "source": {
            "type": "string",
            "enum": [
              "advertising",
              "email",
              "event",
              "hubspot",
              "import",
              "other",
              "partner",
              "phone",
              "referral",
              "web_form"
            ],
            "title": "Source",
            "description": "Where the lead came from."
          },
          "source_detail": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Detail",
            "description": "The campaign, event, list or form."
          },
          "form_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Form Id",
            "description": "The website form that created it."
          },
          "form_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Form Name",
            "description": "That form's name."
          },
          "hubspot_url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Hubspot Url",
            "description": "The HubSpot contact the lead came from (`GET /v1/hubspot`)."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who works on it."
          },
          "email_opt_out": {
            "type": "boolean",
            "title": "Email Opt Out",
            "description": "No sales or marketing e-mails."
          },
          "disqualified_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Disqualified Reason",
            "description": "Why it is not a fit."
          },
          "party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Id",
            "description": "Converted: the customer."
          },
          "party_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Code",
            "description": "The customer's code."
          },
          "party_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Name",
            "description": "The customer's name."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "Converted: the person as its contact."
          },
          "opportunity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Id",
            "description": "Converted: the deal, if one was opened."
          },
          "opportunity_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Number",
            "description": "The deal's number."
          },
          "converted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Converted At",
            "description": "When it was converted (UTC)."
          },
          "converted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Converted By",
            "description": "Who converted it."
          },
          "erased": {
            "type": "boolean",
            "title": "Erased",
            "description": "Its personal data was erased."
          },
          "erased_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Erased At",
            "description": "When (UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it (a form: the form's name)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "status",
          "name",
          "first_name",
          "last_name",
          "company",
          "role",
          "email",
          "phone",
          "country",
          "message",
          "source",
          "source_detail",
          "form_id",
          "form_name",
          "owner",
          "email_opt_out",
          "disqualified_reason",
          "party_id",
          "party_code",
          "party_name",
          "contact_id",
          "opportunity_id",
          "opportunity_number",
          "converted_at",
          "converted_by",
          "erased",
          "erased_at",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "LeadOut",
        "examples": [
          {
            "company": "Beispiel GmbH",
            "country": "DE",
            "created_at": "2026-10-23T09:12:00Z",
            "created_by": {
              "id": "system:web_form",
              "name": "Contact us",
              "type": "system"
            },
            "email": "eva@beispiel.example",
            "email_opt_out": false,
            "entity": "CH01",
            "erased": false,
            "first_name": "Eva",
            "form_id": "9f2a3b4c-5d6e-4f7a-8b8c-9d0e1f2a3b4c",
            "form_name": "Contact us",
            "id": "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
            "last_name": "Beispiel",
            "message": "Please send us a quote for 25 seats.",
            "name": "Eva Beispiel",
            "number": "LEAD-000042",
            "owner": {
              "email": "alice@example.com",
              "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "name": "Alice"
            },
            "role": "Head of Finance",
            "source": "web_form",
            "source_detail": "Contact us",
            "status": "new"
          }
        ]
      },
      "LeadSummary": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Company code."
          },
          "by_status": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "By Status",
            "description": "Leads per status (every status, zeros too)."
          },
          "open_by_source": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Open By Source",
            "description": "Open leads (new, working) per source."
          },
          "unassigned": {
            "type": "integer",
            "title": "Unassigned",
            "description": "Open leads nobody owns."
          },
          "converted_last_30_days": {
            "type": "integer",
            "title": "Converted Last 30 Days",
            "description": "Leads converted in the last 30 days."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "by_status",
          "open_by_source",
          "unassigned",
          "converted_last_30_days"
        ],
        "title": "LeadSummary",
        "description": "How many leads a company has at each status, and where the open ones came from."
      },
      "LeadUpdate": {
        "properties": {
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "disqualified",
                  "new",
                  "working"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "`new`, `working` or `disqualified` (with `disqualified_reason`); a disqualified lead moved back to `new` or `working` loses its reason. Converting is `POST /v1/leads/{lead_id}/convert`."
          },
          "disqualified_reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Disqualified Reason",
            "description": "Why it is not a fit."
          },
          "first_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name",
            "description": "`\"\"` clears."
          },
          "last_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Name",
            "description": "Last name."
          },
          "company": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Company",
            "description": "`\"\"` clears."
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "`\"\"` clears."
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "`\"\"` clears."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "`\"\"` clears."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^([A-Z]{2})?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "`\"\"` clears."
          },
          "message": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 5000
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "`\"\"` clears."
          },
          "source": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "advertising",
                  "email",
                  "event",
                  "hubspot",
                  "import",
                  "other",
                  "partner",
                  "phone",
                  "referral",
                  "web_form"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where the lead came from."
          },
          "source_detail": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Detail",
            "description": "`\"\"` clears."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "string",
                "const": ""
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who works on it; `\"\"` leaves it to nobody."
          },
          "email_opt_out": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email Opt Out",
            "description": "No sales or marketing e-mails."
          }
        },
        "type": "object",
        "title": "LeadUpdate",
        "examples": [
          {
            "owner_user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
            "status": "working"
          },
          {
            "disqualified_reason": "Student project, no budget",
            "status": "disqualified"
          }
        ]
      },
      "LeaseChangeOut": {
        "properties": {
          "effective_date": {
            "type": "string",
            "format": "date",
            "title": "Effective Date",
            "description": "First day of the new payments."
          },
          "from_month": {
            "type": "integer",
            "title": "From Month",
            "description": "The lease month they start in."
          },
          "payment": {
            "type": "string",
            "title": "Payment",
            "description": "The new payment (lease currency)."
          },
          "liability_change": {
            "type": "string",
            "title": "Liability Change",
            "description": "The remeasurement (lease currency)."
          },
          "rou_change": {
            "type": "string",
            "title": "Rou Change",
            "description": "The asset's adjustment (functional currency)."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why the payments changed."
          },
          "entry": {
            "$ref": "#/components/schemas/LeaseEntry",
            "description": "The entry that booked it."
          }
        },
        "type": "object",
        "required": [
          "effective_date",
          "from_month",
          "payment",
          "liability_change",
          "rou_change",
          "reason",
          "entry"
        ],
        "title": "LeaseChangeOut"
      },
      "LeaseEntry": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The journal entry."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number once posted."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, `pending_approval` or `rejected`."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status"
        ],
        "title": "LeaseEntry"
      },
      "LeaseInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code (or id) that holds the lease, e.g. `DE01`."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Left out: the company's next lease number (`L-00001`, counted without gaps). Give one (up to 40 characters, e.g. the contract number) only to keep it; unique in the entity."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What is leased, e.g. `Office Basel`."
          },
          "lessor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lessor",
            "description": "The lessor, a vendor of the entity (code or id); optional."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Currency of the payments, e.g. `EUR`. Default: the entity's functional currency. A foreign-currency liability is revalued at each period end."
          },
          "commencement_date": {
            "type": "string",
            "format": "date",
            "title": "Commencement Date",
            "description": "The day the lessor makes the asset available, ISO 8601; the lease months count from it."
          },
          "term_months": {
            "type": "integer",
            "maximum": 600.0,
            "minimum": 1.0,
            "title": "Term Months",
            "description": "The lease term in months (a multiple of the payment interval)."
          },
          "payment": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Payment",
            "description": "Each payment, e.g. \"450.00\"."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Frequency",
            "description": "`monthly`, `quarterly` or `yearly`. Default `monthly`.",
            "default": "monthly"
          },
          "timing": {
            "type": "string",
            "enum": [
              "advance",
              "arrears"
            ],
            "title": "Timing",
            "description": "`advance` (paid on the first day of its months) or `arrears` (on the last). Default `advance`.",
            "default": "advance"
          },
          "rate_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Rate Percent",
            "description": "The effective annual discount rate in percent, e.g. \"4.5\": the rate implicit in the lease if known, else the incremental borrowing rate. A month is discounted at its twelfth root, (1 + rate) ^ (1/12) - 1."
          },
          "classification": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "finance",
                  "operating"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Classification",
            "description": "`finance` or `operating` (ASC 842-10-25-2). Only a US GAAP company has operating leases: one straight-line lease cost a period instead of interest and depreciation. Default: `operating` for a US GAAP company, `finance` otherwise (IFRS 16 has one model)."
          },
          "initial_direct_costs": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Initial Direct Costs",
            "description": "Initial direct costs, added to the right-of-use asset, in the lease currency.",
            "default": "0"
          },
          "prepaid": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Prepaid",
            "description": "Lease payments made before the commencement date, added to the right-of-use asset, in the lease currency.",
            "default": "0"
          },
          "exemption": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "low_value",
                  "short_term"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption",
            "description": "`short_term` (12 months or less) or `low_value` (IFRS 16.5): the lease is only listed and its bills are expensed. Default null: recognised."
          },
          "rou_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rou Account",
            "description": "Right-of-use asset account. Default: the company's account with the role `lease_right_of_use` (of an operating lease: `operating_lease_right_of_use`)."
          },
          "accumulated_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accumulated Account",
            "description": "Its accumulated depreciation account. Default: the company's account with the role `lease_accumulated_depreciation` (of an operating lease: `operating_lease_accumulated_amortization`)."
          },
          "liability_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Liability Account",
            "description": "Lease liability account. Default: the company's account with the role `lease_liability` (of an operating lease: `operating_lease_liability`)."
          },
          "interest_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interest Account",
            "description": "Interest expense account. Default: the company's account with the role `lease_interest`."
          },
          "depreciation_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Depreciation Account",
            "description": "Depreciation expense account (a finance lease). Default: the company's account with the role `depreciation_expense`."
          },
          "lease_cost_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lease Cost Account",
            "description": "Lease cost account of an operating lease (instead of the interest and depreciation accounts). Default: the company's account with the role `lease_cost`."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name",
          "commencement_date",
          "term_months",
          "payment",
          "rate_percent"
        ],
        "title": "LeaseInput",
        "examples": [
          {
            "code": "L-CAR-01",
            "commencement_date": "2026-08-01",
            "entity": "DE01",
            "frequency": "monthly",
            "name": "Company car",
            "payment": "450.00",
            "rate_percent": "5",
            "term_months": 36,
            "timing": "advance"
          }
        ]
      },
      "LeaseLine": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Lease id."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Lease code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What is leased."
          },
          "lessor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lessor",
            "description": "The lessor's name, if named."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the payments."
          },
          "commencement_date": {
            "type": "string",
            "format": "date",
            "title": "Commencement Date",
            "description": "First day."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "Last day."
          },
          "payment": {
            "type": "string",
            "title": "Payment",
            "description": "The payment now (after any change)."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Frequency",
            "description": "How often it is paid."
          },
          "classification": {
            "type": "string",
            "enum": [
              "finance",
              "operating"
            ],
            "title": "Classification",
            "description": "`finance` or `operating` (US GAAP)."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "draft",
              "exempt",
              "pending",
              "terminated"
            ],
            "title": "Status",
            "description": "`draft`, `pending`, `active`, `terminated` or `exempt`."
          },
          "exemption": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "low_value",
                  "short_term"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption",
            "description": "Why it is only listed, if it is."
          },
          "liability": {
            "type": "string",
            "title": "Liability",
            "description": "Lease liability at `as_of` (lease currency)."
          },
          "current_liability": {
            "type": "string",
            "title": "Current Liability",
            "description": "Of which due within 12 months."
          },
          "rou_carrying": {
            "type": "string",
            "title": "Rou Carrying",
            "description": "Right-of-use asset at `as_of` (functional)."
          },
          "unposted_months": {
            "type": "integer",
            "title": "Unposted Months",
            "description": "Lease months ended by `as_of` not booked yet."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "lessor",
          "currency",
          "commencement_date",
          "end_date",
          "payment",
          "frequency",
          "classification",
          "status",
          "exemption",
          "liability",
          "current_liability",
          "rou_carrying",
          "unposted_months"
        ],
        "title": "LeaseLine"
      },
      "LeaseOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Lease id."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Lease code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What is leased."
          },
          "lessor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lessor",
            "description": "The lessor's name, if named."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the payments."
          },
          "commencement_date": {
            "type": "string",
            "format": "date",
            "title": "Commencement Date",
            "description": "First day."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "Last day."
          },
          "payment": {
            "type": "string",
            "title": "Payment",
            "description": "The payment now (after any change)."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Frequency",
            "description": "How often it is paid."
          },
          "classification": {
            "type": "string",
            "enum": [
              "finance",
              "operating"
            ],
            "title": "Classification",
            "description": "`finance` or `operating` (US GAAP)."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "draft",
              "exempt",
              "pending",
              "terminated"
            ],
            "title": "Status",
            "description": "`draft`, `pending`, `active`, `terminated` or `exempt`."
          },
          "exemption": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "low_value",
                  "short_term"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption",
            "description": "Why it is only listed, if it is."
          },
          "liability": {
            "type": "string",
            "title": "Liability",
            "description": "Lease liability at `as_of` (lease currency)."
          },
          "current_liability": {
            "type": "string",
            "title": "Current Liability",
            "description": "Of which due within 12 months."
          },
          "rou_carrying": {
            "type": "string",
            "title": "Rou Carrying",
            "description": "Right-of-use asset at `as_of` (functional)."
          },
          "unposted_months": {
            "type": "integer",
            "title": "Unposted Months",
            "description": "Lease months ended by `as_of` not booked yet."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The entity's functional currency."
          },
          "local_gaap": {
            "type": "boolean",
            "title": "Local Gaap",
            "description": "The company reports under IFRS or US GAAP on a local chart (Swiss KMU, HGB, ...), whose statutory books expense leases as a rule; a company whose framework is `local` enters no lease."
          },
          "lessor_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lessor Id",
            "description": "The lessor (party id)."
          },
          "lessor_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lessor Code",
            "description": "The lessor's code."
          },
          "term_months": {
            "type": "integer",
            "title": "Term Months",
            "description": "Lease term in months."
          },
          "original_payment": {
            "type": "string",
            "title": "Original Payment",
            "description": "The payment agreed at commencement."
          },
          "timing": {
            "type": "string",
            "enum": [
              "advance",
              "arrears"
            ],
            "title": "Timing",
            "description": "`advance` or `arrears`."
          },
          "rate_percent": {
            "type": "string",
            "title": "Rate Percent",
            "description": "Effective annual discount rate in percent."
          },
          "initial_direct_costs": {
            "type": "string",
            "title": "Initial Direct Costs",
            "description": "Added to the asset (lease currency)."
          },
          "prepaid": {
            "type": "string",
            "title": "Prepaid",
            "description": "Paid before commencement (lease currency)."
          },
          "rou_account": {
            "type": "string",
            "title": "Rou Account",
            "description": "Right-of-use asset account code."
          },
          "accumulated_account": {
            "type": "string",
            "title": "Accumulated Account",
            "description": "Accumulated depreciation account code."
          },
          "liability_account": {
            "type": "string",
            "title": "Liability Account",
            "description": "Lease liability account code."
          },
          "interest_account": {
            "type": "string",
            "title": "Interest Account",
            "description": "Interest expense account code (finance)."
          },
          "depreciation_account": {
            "type": "string",
            "title": "Depreciation Account",
            "description": "Depreciation expense account code (finance)."
          },
          "lease_cost_account": {
            "type": "string",
            "title": "Lease Cost Account",
            "description": "Lease cost account code (operating)."
          },
          "initial_liability": {
            "type": "string",
            "title": "Initial Liability",
            "description": "Liability at commencement (lease currency)."
          },
          "rou_cost": {
            "type": "string",
            "title": "Rou Cost",
            "description": "The asset's cost in the functional currency: as booked once activated, else at the rate of the commencement date (an estimate)."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The date the position figures are at."
          },
          "noncurrent_liability": {
            "type": "string",
            "title": "Noncurrent Liability",
            "description": "Liability due after 12 months."
          },
          "posted_through": {
            "type": "integer",
            "title": "Posted Through",
            "description": "The last lease month booked (0 when none)."
          },
          "activation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LeaseEntry"
              },
              {
                "type": "null"
              }
            ],
            "description": "The entry that recognised the lease."
          },
          "termination_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Termination Date",
            "description": "The day it was ended early."
          },
          "termination": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/LeaseEntry"
              },
              {
                "type": "null"
              }
            ],
            "description": "The entry that derecognised it."
          },
          "changes": {
            "items": {
              "$ref": "#/components/schemas/LeaseChangeOut"
            },
            "type": "array",
            "title": "Changes",
            "description": "Changes of payments, by month."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/LeaseRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "The schedule, month by month (empty if exempt)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "lessor",
          "currency",
          "commencement_date",
          "end_date",
          "payment",
          "frequency",
          "classification",
          "status",
          "exemption",
          "liability",
          "current_liability",
          "rou_carrying",
          "unposted_months",
          "entity",
          "functional_currency",
          "local_gaap",
          "lessor_id",
          "lessor_code",
          "term_months",
          "original_payment",
          "timing",
          "rate_percent",
          "initial_direct_costs",
          "prepaid",
          "rou_account",
          "accumulated_account",
          "liability_account",
          "interest_account",
          "depreciation_account",
          "lease_cost_account",
          "initial_liability",
          "rou_cost",
          "as_of",
          "noncurrent_liability",
          "posted_through",
          "activation",
          "termination_date",
          "termination",
          "changes",
          "rows"
        ],
        "title": "LeaseOut"
      },
      "LeaseRow": {
        "properties": {
          "month": {
            "type": "integer",
            "title": "Month",
            "description": "The lease month, 1 is the first."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "Its first day."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Its last day."
          },
          "opening": {
            "type": "string",
            "title": "Opening",
            "description": "Liability at its start (lease currency)."
          },
          "remeasurement": {
            "type": "string",
            "title": "Remeasurement",
            "description": "A change of payments' remeasurement, else 0."
          },
          "payment": {
            "type": "string",
            "title": "Payment",
            "description": "The payment that falls in it, else 0."
          },
          "interest": {
            "type": "string",
            "title": "Interest",
            "description": "Interest of the month (lease currency)."
          },
          "closing": {
            "type": "string",
            "title": "Closing",
            "description": "Liability at its end (lease currency)."
          },
          "depreciation": {
            "type": "string",
            "title": "Depreciation",
            "description": "Depreciation of the asset (functional currency); of an operating lease the asset's reduction: the lease cost less the interest."
          },
          "lease_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lease Cost",
            "description": "An operating lease's straight-line lease cost of the month (lease currency); null for a finance lease."
          },
          "rou_carrying": {
            "type": "string",
            "title": "Rou Carrying",
            "description": "The asset's carrying amount at its end."
          },
          "posted": {
            "type": "boolean",
            "title": "Posted",
            "description": "Whether a period's lease entries booked it."
          }
        },
        "type": "object",
        "required": [
          "month",
          "start",
          "end",
          "opening",
          "remeasurement",
          "payment",
          "interest",
          "closing",
          "depreciation",
          "lease_cost",
          "rou_carrying",
          "posted"
        ],
        "title": "LeaseRow"
      },
      "LeaseRunItem": {
        "properties": {
          "lease": {
            "type": "string",
            "title": "Lease",
            "description": "Lease code."
          },
          "months": {
            "type": "string",
            "title": "Months",
            "description": "The lease months booked, e.g. `3` or `3-4`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Lease currency (of the interest)."
          },
          "interest": {
            "type": "string",
            "title": "Interest",
            "description": "Interest booked (lease currency)."
          },
          "depreciation": {
            "type": "string",
            "title": "Depreciation",
            "description": "Depreciation booked (functional currency)."
          },
          "classification": {
            "type": "string",
            "enum": [
              "finance",
              "operating"
            ],
            "title": "Classification",
            "description": "`operating`: both were booked as the lease cost."
          },
          "stub": {
            "type": "boolean",
            "title": "Stub",
            "description": "Only the part of lease month 1 that ran by the period's end (the lease commenced in the period and its first month ends after it)."
          }
        },
        "type": "object",
        "required": [
          "lease",
          "months",
          "currency",
          "interest",
          "depreciation",
          "classification",
          "stub"
        ],
        "title": "LeaseRunItem"
      },
      "LeaseRunSummary": {
        "properties": {
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/LeaseRunItem"
            },
            "type": "array",
            "title": "Items",
            "description": "What was booked, one item per lease."
          },
          "skipped": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Skipped",
            "description": "Codes of the leases not booked because a change of their payments waits for approval: decide it, then run again."
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "The entry with the approval policy's decision."
          }
        },
        "type": "object",
        "required": [
          "period",
          "items",
          "skipped",
          "submit"
        ],
        "title": "LeaseRunSummary"
      },
      "LedgerItem": {
        "properties": {
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "The journal entry (`GET /v1/journal-entries/{id}`)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "The entry's number, e.g. `JE-2026-000009`."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "The entry's date, ISO 8601."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "The entry's description."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "What made the entry, e.g. `ap` (a vendor payment) or `manual`."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "How it moved the account, signed (debit positive)."
          }
        },
        "type": "object",
        "required": [
          "entry_id",
          "number",
          "entry_date",
          "description",
          "source",
          "amount"
        ],
        "title": "LedgerItem",
        "description": "A posted entry on the bank account up to the date that no statement line by then shows."
      },
      "LedgerLine": {
        "properties": {
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "Id (uuid) of the journal entry."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "The entry number."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "The posting date (ISO 8601)."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description of the entry."
          },
          "line_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line Description",
            "description": "Description of this line; null if none."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the line."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Debit minus credit in the line's currency (negative on a credit)."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "The debit in the entity's functional currency."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "The credit in the entity's functional currency."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "Running balance after this line, in the functional currency and the account's normal direction."
          },
          "closing": {
            "type": "boolean",
            "title": "Closing",
            "description": "True for a line of a year-end closing entry (source `close`), which brings the profit and loss accounts to zero; the report shows it marked.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "entry_id",
          "number",
          "entry_date",
          "description",
          "line_description",
          "currency",
          "amount",
          "debit",
          "credit",
          "balance"
        ],
        "title": "LedgerLine"
      },
      "Line": {
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Id",
            "description": "BT-126"
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "BT-127"
          },
          "quantity": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity",
            "description": "BT-129"
          },
          "unit_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Code",
            "description": "BT-130 UN/ECE Rec 20"
          },
          "net_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net Amount",
            "description": "BT-131"
          },
          "order_line_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Line Reference",
            "description": "BT-132"
          },
          "accounting_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accounting Reference",
            "description": "BT-133"
          },
          "period_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period Start",
            "description": "BT-134"
          },
          "period_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period End",
            "description": "BT-135"
          },
          "allowances_charges": {
            "items": {
              "$ref": "#/components/schemas/AllowanceCharge"
            },
            "type": "array",
            "title": "Allowances Charges",
            "description": "BG-27/28"
          },
          "net_price": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net Price",
            "description": "BT-146"
          },
          "price_discount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Discount",
            "description": "BT-147"
          },
          "gross_price": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Gross Price",
            "description": "BT-148"
          },
          "base_quantity": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Base Quantity",
            "description": "BT-149"
          },
          "vat_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Category",
            "description": "BT-151"
          },
          "vat_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Rate",
            "description": "BT-152"
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "BT-153"
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "BT-154"
          },
          "seller_item_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Seller Item Id",
            "description": "BT-155"
          },
          "buyer_item_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Item Id",
            "description": "BT-156"
          },
          "standard_item_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Identifier"
              },
              {
                "type": "null"
              }
            ],
            "description": "BT-157"
          },
          "classifications": {
            "items": {
              "$ref": "#/components/schemas/Identifier"
            },
            "type": "array",
            "title": "Classifications",
            "description": "BT-158"
          },
          "origin_country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Origin Country",
            "description": "BT-159"
          }
        },
        "type": "object",
        "title": "Line",
        "description": "BG-25 invoice line."
      },
      "LineInput": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code (or id) in the entry's entity."
          },
          "debit": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Debit",
            "description": "Debit amount in the line's currency, a decimal string such as `1500.00`; zero or omitted on a credit line. Exactly one of debit and credit must be above zero.",
            "default": "0"
          },
          "credit": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Credit",
            "description": "Credit amount in the line's currency, a decimal string such as `1500.00`; zero or omitted on a debit line.",
            "default": "0"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Defaults to functional currency."
          },
          "fx_rate": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fx Rate",
            "description": "Units of functional currency per unit; default the ECB rate of the entry date. On a manual entry a rate more than 10% from that reference rate needs `confirm_rate`."
          },
          "fx_meta": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fx Meta",
            "description": "Provenance of a supplied fx_rate (e.g. an ECB quote)."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text of this line, shown in the general ledger; null when omitted."
          },
          "tax_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Code",
            "description": "VAT treatment code recorded on the line for reporting. Manual entries normally leave it out; the sales and purchase documents set it."
          },
          "tax": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax",
            "description": "VAT tag the VAT report reads: an object with `kind` (`base` or `tax`), `direction`, `jurisdiction`, `treatment` and `rate`. Set by the sales and purchase documents; leave it out on manual entries."
          },
          "counterparty_type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "customer",
                  "entity",
                  "vendor"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Type",
            "description": "`customer` or `vendor`, when the line concerns a customer or vendor; use with `counterparty_id`. `entity` (another entity of the organization) is set by the intercompany postings only; a manual entry is refused with it."
          },
          "counterparty_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Id",
            "description": "Id (uuid) of the customer or vendor the line concerns; null when omitted."
          },
          "subledger_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subledger Type",
            "description": "Kind of subledger record the line belongs to. Set by the subledger services; leave it out on manual entries."
          },
          "subledger_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subledger Id",
            "description": "Id (uuid) of the subledger record the line belongs to. Set by the subledger services; leave it out on manual entries."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "Dimension code to value code, e.g. `{\"cost_centre\": \"CC-100\", \"project\": \"P-17\"}` (`GET /v1/dimensions`); empty when omitted. Each must be an active value of an active dimension, valid on the entry date in its company (`dimension_unknown`, `dimension_value_unknown`); a manual entry gives every dimension its accounts require (`dimension_required`)."
          }
        },
        "type": "object",
        "required": [
          "account"
        ],
        "title": "LineInput",
        "examples": [
          {
            "account": "6500",
            "debit": "1500.00",
            "description": "Audit fee"
          }
        ]
      },
      "LinesInput": {
        "properties": {
          "lines": {
            "items": {
              "$ref": "#/components/schemas/PlanLineInput"
            },
            "type": "array",
            "maxItems": 20000,
            "title": "Lines",
            "description": "Every line of the draft: they replace the lines it has. One amount per account and period; an empty list clears the draft."
          }
        },
        "type": "object",
        "required": [
          "lines"
        ],
        "title": "LinesInput",
        "examples": [
          {
            "lines": [
              {
                "account": "3400",
                "amount": "42000.00",
                "period": "2027-01"
              },
              {
                "account": "5000",
                "amount": "18500.00",
                "period": "2027-01"
              },
              {
                "account": "6000",
                "amount": "3200.00",
                "period": "2027-01"
              }
            ]
          }
        ]
      },
      "LinkInput": {
        "properties": {
          "code": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 1,
            "title": "Code",
            "description": "The one-time code Google's consent popup gave the browser (Google Identity Services' code client, redirect `postmessage`)."
          }
        },
        "type": "object",
        "required": [
          "code"
        ],
        "title": "LinkInput",
        "examples": [
          {
            "code": "4/0AeanS0b..."
          }
        ]
      },
      "LinkOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the link."
          },
          "relationship_id": {
            "type": "string",
            "format": "uuid",
            "title": "Relationship Id",
            "description": "The relationship it belongs to."
          },
          "kind": {
            "type": "string",
            "enum": [
              "credit_note",
              "invoice"
            ],
            "title": "Kind",
            "description": "`invoice` (a sales invoice and its purchase bill) or `credit_note`."
          },
          "status": {
            "type": "string",
            "enum": [
              "accepted",
              "drafted",
              "mirror_rejected",
              "pending",
              "rejected",
              "waiting"
            ],
            "title": "Status",
            "description": "`pending` (the counterpart could not be made: `error` says why; `POST /v1/ic/links/{id}/retry`), `waiting` (a credit note whose invoice's mirror is not posted), `drafted` (the counterpart is a draft a person accepts), `accepted` (posted), `rejected` (the receiver refused it; the sender corrects with a credit note) or `mirror_rejected` (a credit note of an invoice whose mirror was rejected: nothing to credit)."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Document currency of both documents."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "The origin's net total: the counterpart must equal it to be posted."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why the counterpart could not be made, while pending."
          },
          "origin": {
            "$ref": "#/components/schemas/DocumentRef",
            "description": "The document that was posted."
          },
          "counter": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DocumentRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The counterpart in the other entity; null while pending or waiting."
          },
          "origin_posted_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Origin Posted By",
            "description": "Who posted the origin: this person does not accept the mirror."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the origin was posted and linked (UTC)."
          },
          "accepted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accepted By",
            "description": "Who accepted (posted) the mirror."
          },
          "accepted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accepted At",
            "description": "When (UTC)."
          },
          "rejected_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rejected By",
            "description": "Who rejected the mirror."
          },
          "rejected_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rejected At",
            "description": "When (UTC)."
          },
          "reject_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reject Reason",
            "description": "Why it was rejected."
          }
        },
        "type": "object",
        "required": [
          "id",
          "relationship_id",
          "kind",
          "status",
          "currency",
          "net_total",
          "error",
          "origin",
          "counter",
          "origin_posted_by",
          "created_at",
          "accepted_by",
          "accepted_at",
          "rejected_by",
          "rejected_at",
          "reject_reason"
        ],
        "title": "LinkOut",
        "examples": [
          {
            "counter": {
              "document_date": "2026-09-21",
              "document_id": "7c2d6a0e-2a64-4d36-b0a3-9e5a1d6f2c02",
              "entity": "DE01",
              "kind": "purchase_bill",
              "party_code": "IC-CH01",
              "status": "draft",
              "total": "10000.00"
            },
            "created_at": "2026-09-21T10:15:00Z",
            "currency": "CHF",
            "id": "e3a1f0b2-6d7c-4b8a-9c0d-1e2f3a4b5c03",
            "kind": "invoice",
            "net_total": "10000.00",
            "origin": {
              "document_date": "2026-09-21",
              "document_id": "0b9b8a53-1c4e-4f3a-8f55-3f2c3b8a6d01",
              "entity": "CH01",
              "kind": "sales_invoice",
              "number": "INV-2026-000001",
              "party_code": "IC-DE01",
              "status": "posted",
              "total": "10000.00"
            },
            "origin_posted_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "relationship_id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
            "status": "drafted"
          }
        ]
      },
      "LinkRequest": {
        "properties": {
          "payment": {
            "type": "string",
            "title": "Payment",
            "description": "Id or number of a payment already booked from the line's bank account (a candidate of kind `payment`), which the line executes."
          },
          "on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "On",
            "description": "Posting date of the line's own entry (an exchange difference, the move from payments in transit, or the reversal of a returned payment), ISO 8601: a day in an open period, not before the line's booking date (422 `bank_posting_before_line`). Default: the booking date, or when its period is closed the first day of the next open period (the line's `posting_date`). The line keeps its booking date on the statement."
          }
        },
        "type": "object",
        "required": [
          "payment"
        ],
        "title": "LinkRequest",
        "examples": [
          {
            "payment": "PAY-2026-000003"
          }
        ]
      },
      "LinkResult": {
        "properties": {
          "line": {
            "$ref": "#/components/schemas/BankLineOut",
            "description": "The bank line, now `matched` to the payment."
          },
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "title": "Payment Id",
            "description": "Id of the booked payment."
          },
          "payment_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Number",
            "description": "Its number, e.g. `PAY-2026-000003`."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "The bank's amount less the amount the payment booked, in the line's currency (negative when the bank took more); 0 for a payment in the line's currency."
          },
          "difference_entry": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The line's own entry, submitted through the approval policy: for a payment that awaited execution on the payments-in-transit account (ADR-0060), the amount moved from that account to the bank account (with the bank's exchange difference, if any); else the entry that books the difference against the bank account as a realised exchange gain or loss. Null for a payment booked on the bank account without a difference."
          }
        },
        "type": "object",
        "required": [
          "line",
          "payment_id",
          "payment_number",
          "difference",
          "difference_entry"
        ],
        "title": "LinkResult"
      },
      "LoanInput": {
        "properties": {
          "reference": {
            "type": "string",
            "maxLength": 40,
            "minLength": 1,
            "title": "Reference",
            "description": "The loan's reference, unique in the organization."
          },
          "lender": {
            "type": "string",
            "title": "Lender",
            "description": "Code (or id) of the entity that lends."
          },
          "borrower": {
            "type": "string",
            "title": "Borrower",
            "description": "Code (or id) of the entity that borrows."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 3,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency of the loan. Omitted: the lender's functional currency."
          },
          "facility_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Facility Amount",
            "description": "The agreed amount: what may be drawn at most (a decimal string)."
          },
          "interest_rate_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Interest Rate Percent",
            "description": "Fixed annual rate in percent, e.g. `3.0000`."
          },
          "interest_basis": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 3,
            "title": "Interest Basis",
            "description": "The arm's-length basis the approvers accepted, in words (the benchmark, its source and date). Recorded, never judged."
          },
          "day_count": {
            "type": "string",
            "enum": [
              "30/360",
              "act/360",
              "act/365"
            ],
            "title": "Day Count",
            "description": "`act/360`, `act/365` (fixed) or `30/360` (European, 30E/360)."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "First day a drawdown may be dated."
          },
          "maturity_date": {
            "type": "string",
            "format": "date",
            "title": "Maturity Date",
            "description": "The day the loan falls due; after the start."
          },
          "lender_bank_account": {
            "type": "string",
            "title": "Lender Bank Account",
            "description": "Code of the lender's bank account in its chart (an asset account): where drawdowns are paid from and repayments come in."
          },
          "borrower_bank_account": {
            "type": "string",
            "title": "Borrower Bank Account",
            "description": "Code of the borrower's bank account in its chart (an asset account)."
          },
          "net_investment": {
            "type": "boolean",
            "title": "Net Investment",
            "description": "IAS 21.15: settlement is neither planned nor likely, so the loan is part of the net investment in a foreign operation and the consolidation takes its exchange differences to the translation reserve (IAS 21.32).",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "reference",
          "lender",
          "borrower",
          "facility_amount",
          "interest_rate_percent",
          "interest_basis",
          "day_count",
          "start_date",
          "maturity_date",
          "lender_bank_account",
          "borrower_bank_account"
        ],
        "title": "LoanInput",
        "examples": [
          {
            "borrower": "DE01",
            "borrower_bank_account": "1010",
            "currency": "EUR",
            "day_count": "act/360",
            "facility_amount": "500000.00",
            "interest_basis": "3-month EURIBOR of 30 September 2026 plus 0.50 %, the benchmark the tax adviser documented on 25 September 2026",
            "interest_rate_percent": "3.0000",
            "lender": "CH01",
            "lender_bank_account": "1020",
            "maturity_date": "2029-09-30",
            "reference": "L-2026-01",
            "start_date": "2026-10-01"
          }
        ]
      },
      "LoanOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the loan."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "The loan's reference."
          },
          "relationship_id": {
            "type": "string",
            "format": "uuid",
            "title": "Relationship Id",
            "description": "The relationship of the two entities."
          },
          "lender": {
            "type": "string",
            "title": "Lender",
            "description": "Code of the lending entity."
          },
          "borrower": {
            "type": "string",
            "title": "Borrower",
            "description": "Code of the borrowing entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the loan."
          },
          "facility_amount": {
            "type": "string",
            "title": "Facility Amount",
            "description": "What may be drawn at most."
          },
          "interest_rate_percent": {
            "type": "string",
            "title": "Interest Rate Percent",
            "description": "Fixed annual rate in percent."
          },
          "interest_basis": {
            "type": "string",
            "title": "Interest Basis",
            "description": "The arm's-length basis the approvers accepted."
          },
          "day_count": {
            "type": "string",
            "enum": [
              "30/360",
              "act/360",
              "act/365"
            ],
            "title": "Day Count",
            "description": "The day count of the interest."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "First day a drawdown may be dated."
          },
          "maturity_date": {
            "type": "string",
            "format": "date",
            "title": "Maturity Date",
            "description": "The day it falls due."
          },
          "lender_bank_account": {
            "type": "string",
            "title": "Lender Bank Account",
            "description": "The lender's bank account code."
          },
          "lender_bank_balance": {
            "type": "string",
            "title": "Lender Bank Balance",
            "description": "The book balance of the lender's bank account (its posted entries) in the currency it holds (`lender_bank_currency`): where that is the loan's, a drawdown above it takes the account below zero in the books."
          },
          "lender_bank_currency": {
            "type": "string",
            "title": "Lender Bank Currency",
            "description": "The currency the lender's bank account holds (its own, or the lender's functional currency).",
            "default": ""
          },
          "borrower_bank_account": {
            "type": "string",
            "title": "Borrower Bank Account",
            "description": "The borrower's bank account code."
          },
          "net_investment": {
            "type": "boolean",
            "title": "Net Investment",
            "description": "Part of the net investment (IAS 21.15)."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "closed",
              "draft"
            ],
            "title": "Status",
            "description": "`draft` (waits for a second person), `active` or `closed` (repaid in full)."
          },
          "principal": {
            "type": "string",
            "title": "Principal",
            "description": "Principal outstanding: the drawdowns less the repayments recorded."
          },
          "accrued_through": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Accrued Through",
            "description": "The last day interest has been accrued for; null before the first accrual."
          },
          "interest_open": {
            "type": "string",
            "title": "Interest Open",
            "description": "Interest accrued and not settled yet, in the loan's currency."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who asked for it, as an actor object."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved it; null while draft."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When it was approved (UTC)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request that waits (`POST /v1/approvals/{id}/approve`)."
          },
          "closed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed At",
            "description": "When it was repaid in full (UTC)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was requested (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "reference",
          "relationship_id",
          "lender",
          "borrower",
          "currency",
          "facility_amount",
          "interest_rate_percent",
          "interest_basis",
          "day_count",
          "start_date",
          "maturity_date",
          "lender_bank_account",
          "lender_bank_balance",
          "borrower_bank_account",
          "net_investment",
          "status",
          "principal",
          "accrued_through",
          "interest_open",
          "requested_by",
          "approved_by",
          "approved_at",
          "approval_id",
          "closed_at",
          "created_at"
        ],
        "title": "LoanOut"
      },
      "LogLine": {
        "properties": {
          "step": {
            "type": "string",
            "enum": [
              "check",
              "handoff",
              "judgement",
              "note",
              "recheck",
              "rules"
            ],
            "title": "Step",
            "description": "`check` (what was open), `rules` (what code settled), `judgement` (one item the AI worked on), `recheck` (what is open after), `handoff` (what was left to a person), `note` (anything else, e.g. the AI budget used up)."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "What happened, in English; for `judgement`, the item and the AI's account in the outcome's language."
          },
          "count": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Count",
            "description": "For `check`, `rules` and `recheck`: how many items."
          },
          "kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Kind",
            "description": "For `note` and a `rules` that stopped: `budget` (the AI's share used up), `time` (the pass's time for the AI up), `no_ai` (no model available), `busy` (the model busy), `rules_stopped`."
          },
          "item": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item",
            "description": "The item's reference, for `judgement`."
          },
          "tools": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tools",
            "description": "The tools the AI called for the item, in order."
          },
          "settled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settled",
            "description": "For `judgement`: whether the item was settled, as the outcome's own check found afterwards (not as the AI said)."
          }
        },
        "additionalProperties": true,
        "type": "object",
        "required": [
          "step",
          "text"
        ],
        "title": "LogLine"
      },
      "LoginResult": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "choose_organization",
              "passkey",
              "signed_in"
            ],
            "title": "Status",
            "description": "`signed_in` (the session cookie was set), `choose_organization` (the address belongs to several organizations; call again with `org_id`) or `passkey` (touch or create a passkey as `passkey` says, then send the answer to `POST /v1/auth/passkey`)."
          },
          "organizations": {
            "items": {
              "$ref": "#/components/schemas/Membership"
            },
            "type": "array",
            "title": "Organizations",
            "description": "The organizations the address is a user of.",
            "default": []
          },
          "expires_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires At",
            "description": "When the session ends (ISO 8601, UTC); null unless `signed_in`."
          },
          "passkey": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PasskeyStep"
              },
              {
                "type": "null"
              }
            ],
            "description": "The passkey question; null unless `passkey`."
          }
        },
        "type": "object",
        "required": [
          "status"
        ],
        "title": "LoginResult"
      },
      "LogoOut": {
        "properties": {
          "url": {
            "type": "string",
            "title": "Url",
            "description": "Where the PNG is (`GET`, the read scope); changes with the file."
          },
          "width": {
            "type": "integer",
            "title": "Width",
            "description": "Its width in pixels."
          },
          "height": {
            "type": "integer",
            "title": "Height",
            "description": "Its height in pixels."
          },
          "filename": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Filename",
            "description": "The name of the file it was uploaded as."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the stored PNG."
          }
        },
        "type": "object",
        "required": [
          "url",
          "width",
          "height",
          "filename",
          "sha256"
        ],
        "title": "LogoOut"
      },
      "LowestPoint": {
        "properties": {
          "week": {
            "type": "integer",
            "title": "Week",
            "description": "The week whose end has the least cash (0: today's cash)."
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "That week's Sunday (today for week 0)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The cash then."
          },
          "below_zero": {
            "type": "boolean",
            "title": "Below Zero",
            "description": "Whether it is below zero."
          }
        },
        "type": "object",
        "required": [
          "week",
          "date",
          "amount",
          "below_zero"
        ],
        "title": "LowestPoint"
      },
      "MailboxStatus": {
        "properties": {
          "available": {
            "type": "boolean",
            "title": "Available",
            "description": "Whether this system offers the Google link (its OAuth client is set up). False: nothing can be linked yet."
          },
          "client_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Id",
            "description": "The Google OAuth client the browser asks for consent with (the sign-in one)."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "What the consent asks for."
          },
          "linked": {
            "type": "boolean",
            "title": "Linked",
            "description": "Whether your Google account is linked."
          },
          "provider": {
            "anyOf": [
              {
                "type": "string",
                "const": "google"
              },
              {
                "type": "null"
              }
            ],
            "title": "Provider",
            "description": "The linked provider."
          },
          "account_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Email",
            "description": "The linked Google account."
          },
          "mail": {
            "type": "boolean",
            "title": "Mail",
            "description": "Google allowed reading Gmail."
          },
          "calendar": {
            "type": "boolean",
            "title": "Calendar",
            "description": "Google allowed reading the calendar."
          },
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "active",
                  "relink"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "`relink`: Google stopped accepting the link; link again."
          },
          "linked_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Linked At",
            "description": "When it was linked (UTC)."
          },
          "last_sync_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Sync At",
            "description": "When it was last read (UTC)."
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error",
            "description": "Why the last reading failed, in plain words."
          },
          "mail_read_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mail Read To",
            "description": "E-mails are read up to here (UTC)."
          },
          "calendar_read_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Calendar Read To",
            "description": "Meetings are read up to here (UTC)."
          }
        },
        "type": "object",
        "required": [
          "available",
          "client_id",
          "scopes",
          "linked",
          "provider",
          "account_email",
          "mail",
          "calendar",
          "status",
          "linked_at",
          "last_sync_at",
          "last_error",
          "mail_read_to",
          "calendar_read_to"
        ],
        "title": "MailboxStatus"
      },
      "MandateAccountInput": {
        "properties": {
          "debtor_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 140,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Debtor Name",
            "description": "The account holder's name."
          },
          "iban": {
            "type": "string",
            "maxLength": 42,
            "title": "Iban",
            "description": "The customer's new (or same) IBAN."
          },
          "bic": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "BIC of the customer's bank."
          }
        },
        "type": "object",
        "required": [
          "iban"
        ],
        "title": "MandateAccountInput",
        "examples": [
          {
            "bic": "COBADEFFXXX",
            "iban": "DE89 3704 0044 0532 0130 00"
          }
        ]
      },
      "MandateChange": {
        "properties": {
          "approval_id": {
            "type": "string",
            "format": "uuid",
            "title": "Approval Id",
            "description": "The approval request a second person decides."
          },
          "kind": {
            "type": "string",
            "enum": [
              "account",
              "new"
            ],
            "title": "Kind",
            "description": "`new`: the mandate itself waits; `account`: a new IBAN of the debtor."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "The proposed IBAN of an account change."
          },
          "bic": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "The proposed BIC."
          },
          "debtor_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Debtor Name",
            "description": "The proposed account holder."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who asked."
          }
        },
        "type": "object",
        "required": [
          "approval_id",
          "kind",
          "requested_by"
        ],
        "title": "MandateChange"
      },
      "MandateInput": {
        "properties": {
          "reference": {
            "type": "string",
            "pattern": "^[A-Za-z0-9/?:().,'+\\-]{1,35}$",
            "title": "Reference",
            "description": "The mandate reference (Mandatsreferenz) the customer signed, unique for the company in any case: 1 to 35 letters, digits or `/ - ? : ( ) . , ' +`, no space."
          },
          "signed_on": {
            "type": "string",
            "format": "date",
            "title": "Signed On",
            "description": "The day the customer signed the mandate."
          },
          "debtor_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 140,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Debtor Name",
            "description": "The account holder who signed; default the customer's name."
          },
          "iban": {
            "type": "string",
            "maxLength": 42,
            "title": "Iban",
            "description": "The IBAN the customer is debited from (SEPA)."
          },
          "bic": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "BIC of the customer's bank; optional (SEPA)."
          },
          "scheme": {
            "type": "string",
            "enum": [
              "B2B",
              "CORE"
            ],
            "title": "Scheme",
            "description": "`CORE` (SEPA Core, any debtor; 8 weeks' refund right) or `B2B` (SEPA Business to Business: businesses only, no refund, the debtor's bank must hold the mandate too).",
            "default": "CORE"
          },
          "recurring": {
            "type": "boolean",
            "title": "Recurring",
            "description": "`true`: recurring collections (`RCUR`); `false`: one collection only (`OOFF`), after which the mandate is used.",
            "default": true
          },
          "prenotification_days": {
            "type": "integer",
            "maximum": 60.0,
            "minimum": 1.0,
            "title": "Prenotification Days",
            "description": "Calendar days the customer is told of a collection before its date (the invoice is the pre-notification). Default 14 (the rulebook); shorter only as agreed with the customer.",
            "default": 14
          }
        },
        "type": "object",
        "required": [
          "reference",
          "signed_on",
          "iban"
        ],
        "title": "MandateInput",
        "examples": [
          {
            "iban": "DE44 5001 0517 5407 3249 31",
            "recurring": true,
            "reference": "C-HH-2026-01",
            "scheme": "B2B",
            "signed_on": "2026-01-15"
          }
        ]
      },
      "MandateOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the mandate."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity collecting."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Code of the customer."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Name of the customer."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "The mandate reference."
          },
          "signed_on": {
            "type": "string",
            "format": "date",
            "title": "Signed On",
            "description": "Date of signature."
          },
          "debtor_name": {
            "type": "string",
            "title": "Debtor Name",
            "description": "The account holder who signed."
          },
          "iban": {
            "type": "string",
            "title": "Iban",
            "description": "The IBAN debited."
          },
          "bic": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "BIC of the debtor's bank."
          },
          "scheme": {
            "type": "string",
            "enum": [
              "B2B",
              "CORE"
            ],
            "title": "Scheme",
            "description": "`CORE` or `B2B`."
          },
          "recurring": {
            "type": "boolean",
            "title": "Recurring",
            "description": "Recurring (`RCUR`) or one-off (`OOFF`)."
          },
          "prenotification_days": {
            "type": "integer",
            "title": "Prenotification Days",
            "description": "Days of pre-notification."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "expired",
              "pending_approval",
              "rejected",
              "revoked",
              "used"
            ],
            "title": "Status",
            "description": "`pending_approval` (a second person decides), `active`, `rejected`, `revoked`, `expired` (no collection for 36 months, the rulebook) or `used` (a one-off mandate collected once)."
          },
          "first_collected_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Collected On",
            "description": "Date of the first collection sent."
          },
          "last_collected_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Collected On",
            "description": "Date of the last collection sent."
          },
          "expires_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expires On",
            "description": "The day it expires unless collected from before: 36 months after the last collection, or the signature when it was never used; null when it ended otherwise."
          },
          "next_sequence": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "FNAL",
                  "FRST",
                  "OOFF",
                  "RCUR"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Sequence",
            "description": "The sequence type of its next collection (`RCUR` or `OOFF`); null when it cannot be collected from."
          },
          "amendment": {
            "type": "boolean",
            "title": "Amendment",
            "description": "`true` when the debtor's account changed after a collection: the next collection tells the bank (`AmdmntInd`)."
          },
          "pending_change": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MandateChange"
              },
              {
                "type": "null"
              }
            ],
            "description": "What waits for a second person's approval, if anything."
          },
          "revoked_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revoked On",
            "description": "When it was revoked."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was recorded (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "customer",
          "customer_name",
          "reference",
          "signed_on",
          "debtor_name",
          "iban",
          "bic",
          "scheme",
          "recurring",
          "prenotification_days",
          "status",
          "first_collected_on",
          "last_collected_on",
          "expires_on",
          "next_sequence",
          "amendment",
          "pending_change",
          "revoked_on",
          "created_by",
          "created_at"
        ],
        "title": "MandateOut"
      },
      "MarkDemoInput": {
        "properties": {
          "confirm_name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Confirm Name",
            "description": "The organization's exact name, as it is written (no trimming, no case folding): a guard against marking the wrong one."
          }
        },
        "type": "object",
        "required": [
          "confirm_name"
        ],
        "title": "MarkDemoInput",
        "examples": [
          {
            "confirm_name": "Muster Treuhand AG"
          }
        ]
      },
      "MarkDemoResult": {
        "properties": {
          "organization": {
            "$ref": "#/components/schemas/TenantOut",
            "description": "The organization, now of kind `demo`."
          },
          "changed": {
            "type": "boolean",
            "title": "Changed",
            "description": "False when it already was a demo: nothing was changed."
          },
          "evidence": {
            "$ref": "#/components/schemas/OrganizationEvidence",
            "description": "The evidence of use that was measured."
          }
        },
        "type": "object",
        "required": [
          "organization",
          "changed",
          "evidence"
        ],
        "title": "MarkDemoResult"
      },
      "MarkRead": {
        "properties": {
          "ids": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "maxItems": 200,
            "title": "Ids",
            "description": "These notifications."
          },
          "all": {
            "type": "boolean",
            "title": "All",
            "description": "Every unread one of yours.",
            "default": false
          }
        },
        "type": "object",
        "title": "MarkRead",
        "examples": [
          {
            "all": true
          }
        ]
      },
      "MarkSentInput": {
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "portal",
              "post"
            ],
            "title": "Channel",
            "description": "How it was handed over: `email` (a person sent the downloaded file from their own mailbox), `post`, `portal` (the customer's portal) or `other`."
          },
          "recipient": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Recipient",
            "description": "Who got it: an e-mail address, a name or a portal, up to 200 characters."
          },
          "handed_over_on": {
            "type": "string",
            "format": "date",
            "title": "Handed Over On",
            "description": "The day it was handed over (ISO 8601): not before the document date and not in the future."
          },
          "file_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "File Id",
            "description": "The archived output that was handed over (`source` `archived_output` in `GET /v1/documents/{id}/files`). Omitted: the invoice PDF, which is archived now if it was never output."
          }
        },
        "type": "object",
        "required": [
          "channel",
          "recipient",
          "handed_over_on"
        ],
        "title": "MarkSentInput",
        "description": "An invoice handed over outside the system.",
        "examples": [
          {
            "channel": "email",
            "handed_over_on": "2026-09-22",
            "recipient": "buchhaltung@matter-treuhand.example"
          }
        ]
      },
      "MatchLineOut": {
        "properties": {
          "document_line_no": {
            "type": "integer",
            "title": "Document Line No",
            "description": "Number of the bill line."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description on the bill line."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity billed."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Unit price billed."
          },
          "order_line_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Line Id",
            "description": "Id of the order line paired with it; null when the line is not on the order."
          },
          "order_line_no": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Line No",
            "description": "Number of that order line."
          },
          "order_description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Description",
            "description": "Description of that order line."
          },
          "order_unit_price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Unit Price",
            "description": "Unit price on that order line."
          },
          "ordered_quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ordered Quantity",
            "description": "Quantity ordered on that line."
          },
          "received_quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Received Quantity",
            "description": "Received on the order line now, on posted receipts."
          },
          "paired_by": {
            "type": "string",
            "title": "Paired By",
            "description": "reference, description, price, single or none."
          },
          "three_way": {
            "type": "boolean",
            "title": "Three Way",
            "description": "The order line needs a receipt (3-way match)."
          },
          "excess_quantity": {
            "type": "string",
            "title": "Excess Quantity",
            "description": "Quantity billed beyond what was ordered (2-way) or received (3-way)."
          },
          "price_variance": {
            "type": "string",
            "title": "Price Variance",
            "description": "Amount by which the price exceeds the order's, a decimal string."
          },
          "quantity_variance": {
            "type": "string",
            "title": "Quantity Variance",
            "description": "Amount of the excess quantity at the order price, a decimal string."
          },
          "allowed": {
            "type": "string",
            "title": "Allowed",
            "description": "The variance the tolerances allow on the line."
          },
          "within_tolerance": {
            "type": "boolean",
            "title": "Within Tolerance",
            "description": "Whether the line's variance is within the tolerances."
          },
          "similarity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Similarity",
            "description": "How alike the descriptions are, 0 to 1 (pairing evidence)."
          },
          "runner_up_line_no": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Runner Up Line No",
            "description": "The most similar other order line, if any."
          },
          "problem": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Problem",
            "description": "Why the line does not match; null when it does."
          }
        },
        "type": "object",
        "required": [
          "document_line_no",
          "description",
          "quantity",
          "unit_price",
          "order_line_id",
          "order_line_no",
          "order_description",
          "order_unit_price",
          "ordered_quantity",
          "received_quantity",
          "paired_by",
          "three_way",
          "excess_quantity",
          "price_variance",
          "quantity_variance",
          "allowed",
          "within_tolerance",
          "problem"
        ],
        "title": "MatchLineOut"
      },
      "MatchOut": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the bill."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Number of the bill; null before it is posted."
          },
          "order_reference": {
            "type": "string",
            "title": "Order Reference",
            "description": "The order number the bill names (`order_reference`)."
          },
          "order_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Id",
            "description": "Id of the purchase order found; null when none."
          },
          "order_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Number",
            "description": "Number of that order."
          },
          "order_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Status",
            "description": "Status of that order."
          },
          "status": {
            "type": "string",
            "enum": [
              "matched",
              "unmatched",
              "variance"
            ],
            "title": "Status",
            "description": "`matched`, `variance` (payment is blocked until approved) or `unmatched` (the bill quotes an order that is none of its vendor's in its company: its posting waits for a second person)."
          },
          "payment_block": {
            "type": "boolean",
            "title": "Payment Block",
            "description": "A variance nobody approved: the bill is not paid."
          },
          "review": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Review",
            "description": "A paid bill that receipts recorded since would block: why."
          },
          "problems": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Problems",
            "description": "What is wrong, one sentence each; empty when matched."
          },
          "problem_reasons": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/Reason"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Problem Reasons",
            "description": "`problems` by code (`purchaseMatch.problem`) and the values they name, in the same order, for the screens to word; null for a match stored before they were kept."
          },
          "tolerance": {
            "additionalProperties": true,
            "type": "object",
            "title": "Tolerance",
            "description": "The tolerances applied: `percent`, `amount` and `bill_amount`."
          },
          "price_variance": {
            "type": "string",
            "title": "Price Variance",
            "description": "Total price variance of the lines, a decimal string."
          },
          "quantity_variance": {
            "type": "string",
            "title": "Quantity Variance",
            "description": "Total quantity variance of the lines, a decimal string."
          },
          "overcharge": {
            "type": "string",
            "title": "Overcharge",
            "description": "Higher prices, larger quantities, lines not ordered."
          },
          "matched_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Matched By",
            "description": "Who matched the bill (`type`, `id`, `name`)."
          },
          "matched_at": {
            "type": "string",
            "format": "date-time",
            "title": "Matched At",
            "description": "When it was matched (UTC)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "Id of the approval request for the variance; null when none."
          },
          "approval_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Status",
            "description": "`pending`, `approved` or `rejected`; null when none."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved the variance; null while not approved."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When it was approved (UTC)."
          },
          "approval_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Reason",
            "description": "The reason given with the approval."
          },
          "held_approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Held Approved By",
            "description": "Of an `unmatched` bill: the second person who approved its posting, on the approval request that held it because of the unknown order (`type`, `id`, `name`); null while none has (not decided yet, or a bill posted before such bills were held)."
          },
          "held_approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Held Approved At",
            "description": "When that approval was given (UTC); null when none."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/MatchLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The match per bill line."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "document_number",
          "order_reference",
          "order_id",
          "order_number",
          "order_status",
          "status",
          "payment_block",
          "problems",
          "tolerance",
          "price_variance",
          "quantity_variance",
          "overcharge",
          "matched_by",
          "matched_at",
          "approval_id",
          "approval_status",
          "approved_by",
          "approved_at",
          "approval_reason",
          "lines"
        ],
        "title": "MatchOut"
      },
      "MatchRequest": {
        "properties": {
          "allocations": {
            "items": {
              "$ref": "#/components/schemas/AllocationInput-Input"
            },
            "type": "array",
            "title": "Allocations",
            "description": "The documents the line settles, each with the amount applied; with `on_account` the amounts must add up to the absolute amount of the line, and all documents must belong to one customer or vendor."
          },
          "on_account": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "On Account",
            "description": "The part of the line allocated to no document: it stays on the party's account until it is applied (an overpayment, an advance). Default 0.",
            "default": "0"
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the customer or vendor, needed when no document is allocated (the whole line on account); otherwise the documents' party, which it must match."
          },
          "on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "On",
            "description": "Posting date, ISO 8601: a day in an open period, not before the line's booking date (422 `bank_posting_before_line`). Default: the booking date, or when its period is closed the first day of the next open period (the line's `posting_date`). The line keeps its booking date on the statement."
          }
        },
        "type": "object",
        "title": "MatchRequest",
        "examples": [
          {
            "allocations": [
              {
                "amount": "1500.00",
                "document": "INV-2026-000001"
              }
            ]
          }
        ]
      },
      "Me": {
        "properties": {
          "type": {
            "type": "string",
            "title": "Type",
            "description": "`human` or `agent`."
          },
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Actor id: `key:<prefix>` for an API key, `user:<id>` for a signed-in person."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The key's label or the person's email address."
          },
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "Id (uuid) of the organization the credential belongs to."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The scopes held: some of `read`, `draft`, `post`, `approve`, `admin`, `audit`; `admin` implies the others."
          },
          "areas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Areas",
            "description": "The areas of the app the person's role opens (`ledger`, `sales`, `purchasing`, `bank`, `assets`, `close`, `reports`, `stock`, `service`; `GET /v1/roles/areas`); null: every area. An operation outside them answers 403 `area_closed`."
          },
          "org_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Org Name",
            "description": "Name of the organization; null if it cannot be read."
          },
          "auth": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auth",
            "description": "api_key or session"
          },
          "locale": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Locale",
            "description": "The user's UI language; null follows the browser."
          },
          "bound_to": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bound To",
            "description": "The person the credential acts for: the actor id of a user (`user:<id>`). Four eyes and segregation of duties compare people, and a key counts as the person who created it, so a key a signed-in person created is bound to that person. Null when it belongs to no known person (the organization's first key, issued by the system, and every key created with it): it can request but never approve, activate, release or finalise."
          },
          "test_organization": {
            "type": "boolean",
            "title": "Test Organization",
            "description": "`true` for a test organization (a demo, or a test copy made with `POST /v1/test-copies`): its books are not real and it may be removed. A test copy never e-mails customers.",
            "default": false
          },
          "test_copy": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "masked",
                  "unmasked"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Test Copy",
            "description": "A test copy (`POST /v1/test-copies`): `masked` (its people, customers and vendors are made up; its company's bank accounts are real) or `unmasked`; null for any other organization. A test copy makes no payment files, sends no e-mail and puts no QR-bill on its invoices."
          },
          "other_approvers": {
            "type": "integer",
            "title": "Other Approvers",
            "description": "How many people besides this one may approve (users with the `approve` scope, active or invited). 0 means nobody else can approve what this person requests: one's own request always needs a second person, so invite one (`POST /v1/users`, role `controller`), such as the company's accountant.",
            "default": 0
          },
          "approver_acknowledgement_needed": {
            "type": "boolean",
            "title": "Approver Acknowledgement Needed",
            "description": "True when an administrator named this person an approver and they have not yet confirmed that their approvals are recorded in their name (`POST /v1/me/approver-acknowledgement`); they decide nothing before.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "type",
          "id",
          "name",
          "org_id",
          "scopes"
        ],
        "title": "Me"
      },
      "MemberInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the subsidiary entity (a direct subsidiary of the parent)."
          },
          "ownership_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Ownership Percent",
            "description": "The parent's share of the subsidiary, in percent. A percentage with up to four decimals (a decimal string)."
          },
          "control_basis": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 3,
            "title": "Control Basis",
            "description": "The control assessment (IFRS 10.5 to 10.7; Art. 963 para. 2 OR): why the parent controls the subsidiary. It is kept with the approval and is what a second person confirms."
          },
          "acquired_on": {
            "type": "string",
            "format": "date",
            "title": "Acquired On",
            "description": "The date the parent acquired control (ISO 8601)."
          },
          "consolidated_from": {
            "type": "string",
            "format": "date",
            "title": "Consolidated From",
            "description": "The date from which the subsidiary is consolidated and translated: its equity at this date is translated at the rate of the date. Not before `acquired_on`."
          },
          "effective_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Effective From",
            "description": "The group date from which this version applies; default: `consolidated_from`. A run takes the version in force at its date."
          },
          "acquisition_cost": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Cost",
            "description": "What the parent paid for the shares; used by the acquisition entries."
          },
          "acquisition_cost_currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Cost Currency",
            "description": "The currency of `acquisition_cost`; required with it."
          },
          "net_assets_at_acquisition": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net Assets At Acquisition",
            "description": "The fair value of the subsidiary's identifiable net assets at `acquired_on` (IFRS 3.18), in its functional currency. This version takes the book value: it must equal the net assets the subsidiary's ledger holds at that date, else the run reports `fair_value_adjustment_unsupported`. Required, with the cost and the investment account, for the capital consolidation (E4, E5)."
          },
          "investment_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Investment Account",
            "description": "Code of the account in the parent entity that holds the cost of the shares."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "ownership_percent",
          "control_basis",
          "acquired_on",
          "consolidated_from"
        ],
        "title": "MemberInput",
        "examples": [
          {
            "acquired_on": "2026-01-02",
            "acquisition_cost": "800000",
            "acquisition_cost_currency": "CHF",
            "consolidated_from": "2026-01-02",
            "control_basis": "80 % of the voting rights and the right to appoint the management board (IFRS 10.7).",
            "entity": "DE01",
            "ownership_percent": "80"
          }
        ]
      },
      "MemberOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of this version."
          },
          "group": {
            "type": "string",
            "title": "Group",
            "description": "Code of the group."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the subsidiary entity."
          },
          "entity_name": {
            "type": "string",
            "title": "Entity Name",
            "description": "Its name."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its functional currency."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "The version number of this subsidiary in the group, from 1."
          },
          "ownership_percent": {
            "type": "string",
            "title": "Ownership Percent",
            "description": "The parent's share, in percent."
          },
          "method": {
            "type": "string",
            "const": "full",
            "title": "Method",
            "description": "The consolidation method: `full`."
          },
          "control_basis": {
            "type": "string",
            "title": "Control Basis",
            "description": "The control assessment that was approved."
          },
          "goodwill_policy": {
            "type": "string",
            "enum": [
              "amortise",
              "impairment_only",
              "offset_equity"
            ],
            "title": "Goodwill Policy",
            "description": "The group's goodwill policy when approved."
          },
          "acquired_on": {
            "type": "string",
            "format": "date",
            "title": "Acquired On",
            "description": "When control was acquired."
          },
          "consolidated_from": {
            "type": "string",
            "format": "date",
            "title": "Consolidated From",
            "description": "From when it is consolidated."
          },
          "effective_from": {
            "type": "string",
            "format": "date",
            "title": "Effective From",
            "description": "The group date this version applies from."
          },
          "corrects_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Corrects Version",
            "description": "The version this one corrects, or null: a version on the same date as the one before replaces it, and one that keeps the share and the acquisition date but states other purchase data (cost, investment account, net assets) replaces that data from the acquisition on. The corrected version stays in the history."
          },
          "acquisition_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Cost",
            "description": "What was paid for the shares, if recorded."
          },
          "acquisition_cost_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Cost Currency",
            "description": "The currency of the cost."
          },
          "net_assets_at_acquisition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net Assets At Acquisition",
            "description": "Net assets at acquisition, if recorded."
          },
          "investment_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Investment Account",
            "description": "The parent's account holding the cost."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request that was decided, or null when the policy let one person approve."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who requested the version, as an actor object."
          },
          "approved_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Approved By",
            "description": "Who approved it, as an actor object."
          },
          "approved_at": {
            "type": "string",
            "format": "date-time",
            "title": "Approved At",
            "description": "When it was approved (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "group",
          "entity",
          "entity_name",
          "currency",
          "version",
          "ownership_percent",
          "method",
          "control_basis",
          "goodwill_policy",
          "acquired_on",
          "consolidated_from",
          "effective_from",
          "corrects_version",
          "acquisition_cost",
          "acquisition_cost_currency",
          "net_assets_at_acquisition",
          "investment_account",
          "approval_id",
          "requested_by",
          "approved_by",
          "approved_at"
        ],
        "title": "MemberOut"
      },
      "MemberResult": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "approved",
              "pending_approval"
            ],
            "title": "Status",
            "description": "`approved`: the version is in force (the policy let this person approve it); `pending_approval`: a second person decides it."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request when it waits for a second person; else null."
          },
          "member": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/MemberOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The version once approved; null while it waits."
          }
        },
        "type": "object",
        "required": [
          "status",
          "approval_id",
          "member"
        ],
        "title": "MemberResult"
      },
      "Membership": {
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "Id (uuid) of the organization; pass it as `org_id` to choose it."
          },
          "org_name": {
            "type": "string",
            "title": "Org Name",
            "description": "Name of the organization."
          },
          "test_organization": {
            "type": "boolean",
            "title": "Test Organization",
            "description": "`true` for a test organization (a demo or a test copy).",
            "default": false
          },
          "user_id": {
            "type": "string",
            "format": "uuid",
            "title": "User Id",
            "description": "Id (uuid) of the user record in that organization."
          },
          "copy_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Copy Of",
            "description": "For a test copy, the organization it was made from; null for any other."
          }
        },
        "type": "object",
        "required": [
          "org_id",
          "org_name",
          "user_id"
        ],
        "title": "Membership"
      },
      "Message": {
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "assistant",
              "user"
            ],
            "title": "Role",
            "description": "`user` (the default) for what the person wrote, `assistant` for an earlier answer.",
            "default": "user"
          },
          "text": {
            "type": "string",
            "maxLength": 8000,
            "minLength": 1,
            "title": "Text",
            "description": "What was said."
          }
        },
        "type": "object",
        "required": [
          "text"
        ],
        "title": "Message"
      },
      "MessageOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The message's id."
          },
          "kind": {
            "type": "string",
            "enum": [
              "inbound",
              "note",
              "reply"
            ],
            "title": "Kind",
            "description": "`inbound` (from the customer), `reply` (to them) or `note` (internal)."
          },
          "status": {
            "type": "string",
            "enum": [
              "discarded",
              "draft",
              "received",
              "saved",
              "sent"
            ],
            "title": "Status",
            "description": "`received` (inbound), `saved` (note), `draft`, `sent` or `discarded`."
          },
          "sent_via": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "email",
                  "outside"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Sent Via",
            "description": "A sent reply: `email` from here, or `outside` (answered elsewhere)."
          },
          "from_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Address",
            "description": "The sender's address."
          },
          "from_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Name",
            "description": "The sender's name."
          },
          "to": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "To",
            "description": "The recipients."
          },
          "subject": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject",
            "description": "The subject."
          },
          "body": {
            "type": "string",
            "title": "Body",
            "description": "The text."
          },
          "message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message Id",
            "description": "The e-mail's Message-ID."
          },
          "source": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "api",
                  "google_mail"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "How an inbound message came: a linked Gmail inbox or the API."
          },
          "auto": {
            "type": "boolean",
            "title": "Auto",
            "description": "An automatic message (out of office, bounce)."
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "title": "At",
            "description": "When it was received or sent (UTC)."
          },
          "sent_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sent By",
            "description": "Who sent the reply (actor object)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who wrote or recorded it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed the draft last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "status",
          "sent_via",
          "from_address",
          "from_name",
          "to",
          "subject",
          "body",
          "message_id",
          "source",
          "auto",
          "at",
          "sent_by",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "MessageOut"
      },
      "ModelCheck": {
        "properties": {
          "model": {
            "type": "string",
            "title": "Model",
            "description": "The model asked."
          },
          "ok": {
            "type": "boolean",
            "title": "Ok",
            "description": "True when the model answered a short test request."
          },
          "seconds": {
            "type": "number",
            "title": "Seconds",
            "description": "How long it took to answer or fail."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "What went wrong, when it did not answer."
          }
        },
        "type": "object",
        "required": [
          "model",
          "ok",
          "seconds",
          "error"
        ],
        "title": "ModelCheck"
      },
      "ModelCheckInput": {
        "properties": {
          "model": {
            "type": "string",
            "pattern": "^(gemini|claude)-[a-z0-9][a-z0-9.@-]{0,79}$",
            "title": "Model",
            "description": "A Vertex AI model id of the Gemini or Claude family, e.g. `gemini-3.8-flash` or `claude-opus-5-5`."
          }
        },
        "type": "object",
        "required": [
          "model"
        ],
        "title": "ModelCheckInput",
        "examples": [
          {
            "model": "gemini-3.8-flash"
          }
        ]
      },
      "ModelChoiceInput": {
        "properties": {
          "models": {
            "items": {
              "type": "string",
              "pattern": "^(gemini|claude)-[a-z0-9][a-z0-9.@-]{0,79}$",
              "description": "A Vertex AI model id of the Gemini or Claude family, e.g. `gemini-3.8-flash` or `claude-opus-5-5`."
            },
            "type": "array",
            "maxItems": 4,
            "minItems": 1,
            "title": "Models",
            "description": "The models to ask, in order: the first answers unless it fails or does not answer, then the next. 1 to 4 ids, each once."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why, for the record (1 to 500 characters)."
          }
        },
        "type": "object",
        "required": [
          "models"
        ],
        "title": "ModelChoiceInput",
        "examples": [
          {
            "models": [
              "gemini-3.8-flash",
              "gemini-3.7-flash"
            ],
            "reason": "3.7 as the fallback while 3.8 is in preview"
          }
        ]
      },
      "ModelChoiceOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the choice."
          },
          "models": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Models",
            "description": "The models, in the order they are asked."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was chosen (ISO 8601, UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who chose it: `type`, `id`, `name`, `email`."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why, as given."
          }
        },
        "type": "object",
        "required": [
          "id",
          "models",
          "created_at",
          "created_by",
          "reason"
        ],
        "title": "ModelChoiceOut"
      },
      "ModelSettings": {
        "properties": {
          "models": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Models",
            "description": "The models the built-in agents ask now, in order (the first, then each fallback)."
          },
          "source": {
            "type": "string",
            "enum": [
              "deployment",
              "operator"
            ],
            "title": "Source",
            "description": "`operator`: the latest choice made here; `deployment`: none was made, so the defaults of the deployment apply (`ERP_LLM_PROVIDER`, `ERP_LLM_MODEL`, `ERP_LLM_FALLBACK_MODELS`)."
          },
          "last_resort": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Last Resort",
            "description": "With an operator's choice, the deployment's defaults asked after it when every chosen model fails, so that an id Vertex AI does not serve cannot stop the agents."
          },
          "not_listed": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Not Listed",
            "description": "Chosen Gemini models that are not in `available`: possibly a typo or a retired model. Empty when the list could not be read."
          },
          "deployment_default": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Deployment Default",
            "description": "The deployment's defaults, which apply when no choice was made."
          },
          "region": {
            "type": "string",
            "title": "Region",
            "description": "The Vertex AI location the models are called at."
          },
          "configured": {
            "type": "boolean",
            "title": "Configured",
            "description": "False when no Google Cloud project is configured: the agents answer 503."
          },
          "available": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Available",
            "description": "The Gemini text models Google lists for the project at `region` now (embedding models left out). Claude models are not listed by Google: enable one in Model Garden, then enter its id."
          },
          "available_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Available Error",
            "description": "Why the list of available models could not be read, if it could not."
          },
          "history": {
            "items": {
              "$ref": "#/components/schemas/ModelChoiceOut"
            },
            "type": "array",
            "title": "History",
            "description": "The latest choices, newest first."
          }
        },
        "type": "object",
        "required": [
          "models",
          "source",
          "last_resort",
          "not_listed",
          "deployment_default",
          "region",
          "configured",
          "available",
          "available_error",
          "history"
        ],
        "title": "ModelSettings"
      },
      "MovementInput": {
        "properties": {
          "value_date": {
            "type": "string",
            "format": "date",
            "title": "Value Date",
            "description": "The day the money moves; both entries are dated it."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "In the loan's currency (a decimal string)."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Your reference, e.g. the bank's; optional."
          }
        },
        "type": "object",
        "required": [
          "value_date",
          "amount"
        ],
        "title": "MovementInput",
        "examples": [
          {
            "amount": "500000.00",
            "value_date": "2026-10-01"
          }
        ]
      },
      "MovementOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the movement."
          },
          "kind": {
            "type": "string",
            "enum": [
              "dividend_declared",
              "interest_accrual",
              "loan_drawdown",
              "loan_repayment",
              "settlement"
            ],
            "title": "Kind",
            "description": "What moved."
          },
          "relationship_id": {
            "type": "string",
            "format": "uuid",
            "title": "Relationship Id",
            "description": "The relationship of the two entities."
          },
          "loan_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Loan Id",
            "description": "The loan; null for a dividend."
          },
          "loan_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Loan Reference",
            "description": "The loan's reference."
          },
          "value_date": {
            "type": "string",
            "format": "date",
            "title": "Value Date",
            "description": "The day of the movement."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "In `currency`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the movement."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "Reference."
          },
          "creditor": {
            "$ref": "#/components/schemas/EntryRef",
            "description": "The lender's entry (the shareholder's for a dividend)."
          },
          "debtor": {
            "$ref": "#/components/schemas/EntryRef",
            "description": "The borrower's entry (the declaring entity's for a dividend)."
          },
          "settles_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settles Id",
            "description": "What a settlement settles."
          },
          "detail": {
            "additionalProperties": true,
            "type": "object",
            "title": "Detail",
            "description": "For interest: `from`, `through` and the `segments` (principal and days); for a repayment or settlement the realised exchange differences."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it, as an actor object."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "What to know that did not stop it, when it was recorded, in English: that it takes the paying bank account below zero in the books on the value date (the lender's for a drawdown, the borrower's for a repayment or a settlement)."
          },
          "warning_reasons": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Warning Reasons",
            "description": "The same by code (`bankBalance.warning.overdrawn`, with `account`, `entity`, `balance`, `after`, `currency` and `on`; `overdrawn_in_transit` adds `in_transit` when payments the bank has not executed yet count towards it), in the order of `warnings`."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "relationship_id",
          "loan_id",
          "loan_reference",
          "value_date",
          "amount",
          "currency",
          "reference",
          "creditor",
          "debtor",
          "settles_id",
          "detail",
          "created_by",
          "created_at"
        ],
        "title": "MovementOut"
      },
      "MrrMonth": {
        "properties": {
          "month": {
            "type": "string",
            "title": "Month",
            "description": "`YYYY-MM`."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day MRR is read: the month's last day, or today for the current month."
          },
          "fixing_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fixing Date",
            "description": "The ECB fixing that converts the month's amounts (the latest on or before `as_of`); null when there is none (other currencies are then in `unconverted`)."
          },
          "opening": {
            "$ref": "#/components/schemas/Figure",
            "description": "MRR at the end of the month before."
          },
          "new": {
            "$ref": "#/components/schemas/Figure",
            "description": "MRR of customers who had none ever before."
          },
          "expansion": {
            "$ref": "#/components/schemas/Figure",
            "description": "More MRR from customers who had some at both ends."
          },
          "contraction": {
            "$ref": "#/components/schemas/Figure",
            "description": "Negative."
          },
          "churn": {
            "$ref": "#/components/schemas/Figure",
            "description": "Negative."
          },
          "reactivation": {
            "$ref": "#/components/schemas/Figure",
            "description": "MRR of customers who had some before, but not at the month before's end."
          },
          "currency_effect": {
            "type": "string",
            "title": "Currency Effect",
            "description": "In the report's currency: the opening MRR's change of value from the month before's fixing to this month's (and the cents of converting each customer on its own), so that opening + movements + currency effect = closing."
          },
          "closing": {
            "$ref": "#/components/schemas/Figure",
            "description": "MRR at `as_of`: every subscription line in force that day."
          },
          "arr": {
            "$ref": "#/components/schemas/Figure",
            "description": "Annual recurring revenue: 12 x the closing MRR."
          },
          "customers_opening": {
            "type": "integer",
            "title": "Customers Opening",
            "description": "Customers with MRR at the month before's end."
          },
          "customers": {
            "type": "integer",
            "title": "Customers",
            "description": "Customers with MRR at `as_of`."
          },
          "new_customers": {
            "type": "integer",
            "title": "New Customers",
            "description": "Customers with a `new` movement."
          },
          "churned_customers": {
            "type": "integer",
            "title": "Churned Customers",
            "description": "Customers with a `churn` movement."
          },
          "reactivated_customers": {
            "type": "integer",
            "title": "Reactivated Customers",
            "description": "Customers with a `reactivation` movement."
          },
          "customer_churn_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Churn Rate",
            "description": "Churned customers over the opening customers, in percent (one decimal); null without opening customers."
          },
          "mrr_churn_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mrr Churn Rate",
            "description": "Gross MRR churn: churn and contraction over the opening MRR (both at this month's fixing), in percent; null without opening MRR."
          },
          "net_mrr_retention": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net Mrr Retention",
            "description": "The opening MRR kept, with expansion and less contraction and churn, over the opening MRR (both at this month's fixing), in percent; new and reactivated customers are not counted. Null without opening MRR."
          },
          "movements": {
            "items": {
              "$ref": "#/components/schemas/MrrMovement"
            },
            "type": "array",
            "title": "Movements",
            "description": "Each customer's movement, the largest first."
          }
        },
        "type": "object",
        "required": [
          "month",
          "as_of",
          "fixing_date",
          "opening",
          "new",
          "expansion",
          "contraction",
          "churn",
          "reactivation",
          "currency_effect",
          "closing",
          "arr",
          "customers_opening",
          "customers",
          "new_customers",
          "churned_customers",
          "reactivated_customers",
          "customer_churn_rate",
          "mrr_churn_rate",
          "net_mrr_retention",
          "movements"
        ],
        "title": "MrrMonth"
      },
      "MrrMovement": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "churn",
              "contraction",
              "expansion",
              "new",
              "reactivation"
            ],
            "title": "Kind",
            "description": "`new`: the customer's first MRR; `expansion` / `contraction`: more or less MRR from a customer who had some at the month before's end and still has; `churn`: all of it gone; `reactivation`: MRR again from a customer who had some before, but not at the month before's end."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "The customer's id."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "The customer's code."
          },
          "party_name": {
            "type": "string",
            "title": "Party Name",
            "description": "The customer's name."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency the customer's subscriptions bill in."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The change of MRR in that currency (negative: less)."
          },
          "converted": {
            "type": "string",
            "title": "Converted",
            "description": "The change in the report's currency, at the month's fixing."
          },
          "subscriptions": {
            "items": {
              "$ref": "#/components/schemas/SubscriptionRef"
            },
            "type": "array",
            "title": "Subscriptions",
            "description": "The subscriptions whose MRR changed."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "party_id",
          "party_code",
          "party_name",
          "currency",
          "amount",
          "converted",
          "subscriptions"
        ],
        "title": "MrrMovement"
      },
      "MyRecordAccess": {
        "properties": {
          "record_visibility": {
            "type": "string",
            "enum": [
              "all",
              "own",
              "team"
            ],
            "title": "Record Visibility",
            "description": "Which sales records the person sees: `all` (every customer, contact, deal and activity), `team` (the records they or anyone in a team of theirs own) or `own` (the records they own). A key or an agent sees what the person behind it sees; a key the system issued sees every record."
          },
          "people": {
            "items": {
              "$ref": "#/components/schemas/Person"
            },
            "type": "array",
            "title": "People",
            "description": "With `team` or `own`: the people whose records you see (you first); empty with `all`."
          }
        },
        "type": "object",
        "required": [
          "record_visibility",
          "people"
        ],
        "title": "MyRecordAccess"
      },
      "Need": {
        "properties": {
          "domain": {
            "type": "string",
            "title": "Domain",
            "description": "The kind of reference data, e.g. a tax rate or exchange rate dataset."
          },
          "domain_title": {
            "type": "string",
            "title": "Domain Title",
            "description": "Its name in words."
          },
          "jurisdictions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Jurisdictions",
            "description": "Jurisdictions the entities need it for."
          },
          "reasons": {
            "items": {
              "$ref": "#/components/schemas/NeedReason"
            },
            "type": "array",
            "title": "Reasons",
            "description": "Which entities and features need it, and why."
          },
          "state": {
            "type": "string",
            "enum": [
              "error",
              "gap",
              "no_data",
              "ok",
              "stale",
              "unknown"
            ],
            "title": "State",
            "description": "`ok`, `stale`, `no_data`, `error`, `gap` (no authority registered) or `unknown`."
          },
          "source": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DataSource"
              },
              {
                "type": "null"
              }
            ],
            "description": "None: a gap (or unknown)."
          }
        },
        "type": "object",
        "required": [
          "domain",
          "domain_title",
          "jurisdictions",
          "reasons",
          "state"
        ],
        "title": "Need"
      },
      "NeedReason": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity that needs the data."
          },
          "entity_name": {
            "type": "string",
            "title": "Entity Name",
            "description": "Name of that entity."
          },
          "feature": {
            "type": "string",
            "title": "Feature",
            "description": "One of FEATURES (vat_documents, vat_returns, ...)."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "Why it is needed, in a sentence."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "entity_name",
          "feature",
          "text"
        ],
        "title": "NeedReason"
      },
      "NegativeGoodwill": {
        "properties": {
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The negative difference at acquisition."
          },
          "release_years": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Release Years",
            "description": "The years it is released to profit or loss over (FER); null when the group releases it itself (HGB, section 309 para. 2)."
          },
          "released_of_year": {
            "type": "string",
            "title": "Released Of Year",
            "description": "Released in the group year."
          },
          "released": {
            "type": "string",
            "title": "Released",
            "description": "Released up to the group date."
          },
          "closing": {
            "type": "string",
            "title": "Closing",
            "description": "Still on the liability at the group date."
          }
        },
        "type": "object",
        "required": [
          "amount",
          "release_years",
          "released_of_year",
          "released",
          "closing"
        ],
        "title": "NegativeGoodwill",
        "description": "A negative difference at acquisition kept as a liability (Swiss GAAP FER 30/17; under HGB\nthe \"Unterschiedsbetrag aus der Kapitalkonsolidierung\", section 301 para. 3)."
      },
      "NewContact": {
        "properties": {
          "first_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "First Name",
            "description": "First name."
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Role or department, e.g. `Head of purchasing`. A role that says billing, accounting or `Buchhaltung` makes the contact one an invoice goes to by default."
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Phone number."
          },
          "mobile": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Mobile",
            "description": "Mobile number."
          },
          "last_name": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Last Name",
            "description": "Last name. A `name` sent instead is split: its last word is the last name, the words before it the first name."
          }
        },
        "type": "object",
        "required": [
          "last_name"
        ],
        "title": "NewContact",
        "description": "A person at a new customer or vendor."
      },
      "NightPrice": {
        "properties": {
          "night": {
            "type": "string",
            "format": "date",
            "title": "Night",
            "description": "The night."
          },
          "price": {
            "type": "string",
            "title": "Price",
            "description": "Net price of one room, agreed when reserved."
          },
          "season": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Season",
            "description": "The season that priced it; null: the list price."
          }
        },
        "type": "object",
        "required": [
          "night",
          "price",
          "season"
        ],
        "title": "NightPrice"
      },
      "NoteInput": {
        "properties": {
          "body": {
            "type": "string",
            "maxLength": 100000,
            "minLength": 1,
            "title": "Body",
            "description": "The note; never sent."
          }
        },
        "type": "object",
        "required": [
          "body"
        ],
        "title": "NoteInput",
        "examples": [
          {
            "body": "Carrier says the parcel is in Basel."
          }
        ]
      },
      "NotificationList": {
        "properties": {
          "unread": {
            "type": "integer",
            "title": "Unread",
            "description": "How many of yours are unread."
          },
          "approvals_waiting": {
            "type": "integer",
            "title": "Approvals Waiting",
            "description": "Approval requests you may decide now (four eyes): the Approvals page lists them."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/NotificationOut"
            },
            "type": "array",
            "title": "Items",
            "description": "Yours, the newest first."
          }
        },
        "type": "object",
        "required": [
          "unread",
          "approvals_waiting",
          "items"
        ],
        "title": "NotificationList"
      },
      "NotificationOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The notification's id (to mark it read)."
          },
          "kind": {
            "type": "string",
            "enum": [
              "approval_decided",
              "deal_assigned",
              "deal_lost",
              "deal_won",
              "task_assigned",
              "task_due",
              "task_overdue",
              "webhook_disabled"
            ],
            "title": "Kind",
            "description": "What happened: `task_assigned` (someone gave you a task), `task_due` (a task of yours is due), `task_overdue` (its day passed), `deal_assigned` (someone made you a deal's owner), `deal_won`, `deal_lost` (a deal you own, moved by someone else), `approval_decided` (your request was approved or rejected), `webhook_disabled` (an endpoint kept failing and was stopped; administrators)."
          },
          "params": {
            "additionalProperties": true,
            "type": "object",
            "title": "Params",
            "description": "The values the screen words it with, by kind: `subject`, `due_on`, `deal`, `customer`, `by` (who did it), `number`, `title`, `amount`, `currency`, `reason`, `status`, `object_type`, `url`."
          },
          "link": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Link",
            "description": "Where the web UI opens it (a path)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it happened."
          },
          "read_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Read At",
            "description": "When you read it; null while unread."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "params",
          "link",
          "created_at",
          "read_at"
        ],
        "title": "NotificationOut"
      },
      "NotificationSettings": {
        "properties": {
          "email_kinds": {
            "items": {
              "type": "string",
              "enum": [
                "approval_decided",
                "deal_assigned",
                "deal_lost",
                "deal_won",
                "task_assigned",
                "task_due",
                "task_overdue",
                "webhook_disabled"
              ]
            },
            "type": "array",
            "title": "Email Kinds",
            "description": "The kinds you also get by e-mail (none by default). Every notification is in the notification centre whatever this says."
          }
        },
        "type": "object",
        "required": [
          "email_kinds"
        ],
        "title": "NotificationSettings",
        "examples": [
          {
            "email_kinds": [
              "task_assigned",
              "task_due"
            ]
          }
        ]
      },
      "NotificationSettingsOut": {
        "properties": {
          "email_kinds": {
            "items": {
              "type": "string",
              "enum": [
                "approval_decided",
                "deal_assigned",
                "deal_lost",
                "deal_won",
                "task_assigned",
                "task_due",
                "task_overdue",
                "webhook_disabled"
              ]
            },
            "type": "array",
            "title": "Email Kinds",
            "description": "The kinds you also get by e-mail (none by default). Every notification is in the notification centre whatever this says."
          },
          "email_available": {
            "type": "boolean",
            "title": "Email Available",
            "description": "Whether this system sends e-mail (a mail server is set up and this is not a test copy). False: the choice is kept and nothing is sent."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Where e-mail goes: your sign-in address."
          }
        },
        "type": "object",
        "required": [
          "email_kinds",
          "email_available",
          "email"
        ],
        "title": "NotificationSettingsOut",
        "examples": [
          {
            "email_kinds": [
              "task_assigned",
              "task_due"
            ]
          }
        ]
      },
      "ObligationInput": {
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Description",
            "description": "What is promised."
          },
          "product": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product",
            "description": "Code (or id) of a product of the entity (`GET /v1/products`). It gives the revenue account and, when `ssp` is omitted, the SSP in force on the contract's start day, with its basis."
          },
          "pattern": {
            "type": "string",
            "enum": [
              "over_time",
              "point_in_time"
            ],
            "title": "Pattern",
            "description": "`over_time` (revenue as the service is given, over `service_start` to `service_end`) or `point_in_time` (revenue when a person records that control transferred: `POST /v1/revenue-obligations/{obligation_id}/satisfy`)."
          },
          "method": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "monthly",
                  "straight_line"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Over time: `straight_line` (by days) or `monthly` (each calendar month the same, a part of a month by its days); default `straight_line`. None at a point in time."
          },
          "service_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Service Start",
            "description": "Over time: the first day of service; default the contract's."
          },
          "service_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Service End",
            "description": "Over time: the last day of service; default the contract's."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Quantity",
            "description": "With a product and no `ssp`: how many units (seats, days) the obligation is; the product's SSP is per unit, and for a recurring product per month or year, so the obligation's SSP is the unit SSP times the quantity times the months (or years) of its service period.",
            "default": "1"
          },
          "ssp": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ssp",
            "description": "Standalone selling price of the whole obligation, in the contract's currency; required without a product SSP."
          },
          "ssp_basis": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Ssp Basis",
            "description": "How the SSP was established (IFRS 15.77-79); required with `ssp`."
          },
          "revenue_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revenue Account",
            "description": "Revenue account (code or id); default the product's, else the entity's default revenue account."
          }
        },
        "type": "object",
        "required": [
          "description",
          "pattern"
        ],
        "title": "ObligationInput"
      },
      "ObligationOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Obligation id."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Position, from 1."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What is promised."
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Id",
            "description": "The product."
          },
          "pattern": {
            "type": "string",
            "enum": [
              "over_time",
              "point_in_time"
            ],
            "title": "Pattern",
            "description": "`over_time` or `point_in_time`."
          },
          "method": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "monthly",
                  "straight_line"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Over time: the method."
          },
          "service_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Service Start",
            "description": "Over time: the first day of service."
          },
          "service_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Service End",
            "description": "Over time: the last day of service."
          },
          "ssp": {
            "type": "string",
            "title": "Ssp",
            "description": "Standalone selling price."
          },
          "ssp_basis": {
            "type": "string",
            "title": "Ssp Basis",
            "description": "How it was established."
          },
          "allocated_price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allocated Price",
            "description": "Its part of the transaction price; null until the contract is activated."
          },
          "revenue_account": {
            "type": "string",
            "title": "Revenue Account",
            "description": "Code of the revenue account."
          },
          "status": {
            "type": "string",
            "enum": [
              "cancelled",
              "open",
              "satisfied"
            ],
            "title": "Status",
            "description": "The status."
          },
          "satisfied_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Satisfied On",
            "description": "Point in time: when control transferred."
          },
          "satisfied_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Satisfied By",
            "description": "Who recorded it."
          },
          "satisfaction_evidence": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Satisfaction Evidence",
            "description": "What shows it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "line_no",
          "description",
          "product_id",
          "pattern",
          "method",
          "service_start",
          "service_end",
          "ssp",
          "ssp_basis",
          "allocated_price",
          "revenue_account",
          "status",
          "satisfied_on",
          "satisfied_by",
          "satisfaction_evidence"
        ],
        "title": "ObligationOut"
      },
      "OnAccountRefundInput": {
        "properties": {
          "payment_date": {
            "type": "string",
            "format": "date",
            "title": "Payment Date",
            "description": "Value date of the refund (ISO 8601), on or after the payment it pays back and its latest application, in an open period. A refund received (from a vendor) is not dated after today (`receipt_in_future`), nor is one paid (`payment_in_future`)."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Amount paid back, in the payment's currency: at most what is left on account (`more_than_left_to_apply`)."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "GL bank account code; default: the main bank account for the currency."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Free text reference."
          },
          "executed": {
            "type": "boolean",
            "title": "Executed",
            "description": "A refund paid out only: `true` when the bank already executed it; it is booked on the bank account at once and goes into no payment file. Default `false`: it awaits execution on the payments-in-transit account until its bank line is matched (ADR-0060).",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "payment_date",
          "amount"
        ],
        "title": "OnAccountRefundInput",
        "description": "Paying back an amount kept on account: a customer's overpayment, or a vendor's refund of an\nadvance paid to it.",
        "examples": [
          {
            "amount": "185.78",
            "payment_date": "2026-10-11",
            "reference": "Refund"
          }
        ]
      },
      "OnlineAcceptInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "Your full name."
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 320
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Your e-mail address."
          },
          "revision": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Revision",
            "description": "The version you read (`revision` of the page)."
          },
          "agree": {
            "type": "boolean",
            "const": true,
            "title": "Agree",
            "description": "You accept the quote for your company."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "Your purchase order number, if any."
          }
        },
        "type": "object",
        "required": [
          "name",
          "revision",
          "agree"
        ],
        "title": "OnlineAcceptInput",
        "examples": [
          {
            "agree": true,
            "customer_reference": "PO-4711",
            "email": "anna@werkstatt.example",
            "name": "Anna Muster",
            "revision": 2
          }
        ]
      },
      "OnlineDeclineInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "Your full name."
          },
          "email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 320
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Your e-mail address."
          },
          "revision": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Revision",
            "description": "The version you read."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why, if you like."
          }
        },
        "type": "object",
        "required": [
          "name",
          "revision"
        ],
        "title": "OnlineDeclineInput",
        "examples": [
          {
            "name": "Anna Muster",
            "reason": "Budget",
            "revision": 1
          }
        ]
      },
      "OnlineLine": {
        "properties": {
          "position": {
            "type": "integer",
            "title": "Position",
            "description": "Position, from 1."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What is offered."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net unit price."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "Line discount in percent, if asked so."
          },
          "discount_amount": {
            "type": "string",
            "title": "Discount Amount",
            "description": "Line discount in money; 0 for none."
          },
          "vat_rate": {
            "type": "string",
            "title": "Vat Rate",
            "description": "VAT rate in percent."
          },
          "net_amount": {
            "type": "string",
            "title": "Net Amount",
            "description": "Net of the line after its own discount."
          }
        },
        "type": "object",
        "required": [
          "position",
          "description",
          "quantity",
          "unit_price",
          "discount_percent",
          "discount_amount",
          "vat_rate",
          "net_amount"
        ],
        "title": "OnlineLine"
      },
      "OnlineVat": {
        "properties": {
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "VAT rate in percent."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The tax's name where a line bears several."
          },
          "net": {
            "type": "string",
            "title": "Net",
            "description": "Net at this rate."
          },
          "tax": {
            "type": "string",
            "title": "Tax",
            "description": "VAT at this rate."
          }
        },
        "type": "object",
        "required": [
          "rate",
          "name",
          "net",
          "tax"
        ],
        "title": "OnlineVat"
      },
      "OpenCredit": {
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "credit_note",
              "payment"
            ],
            "title": "Source",
            "description": "`payment` (an amount on account) or `credit_note`."
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the payment or credit note."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number, e.g. `RCPT-2026-000004` or `CN-2026-000003`."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "The payment's direction (`incoming`, `outgoing`) or the credit note's kind (`sales_credit_note`, `purchase_credit_note`)."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer or vendor."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer or vendor."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer or vendor."
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "Payment date, or credit note date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the amounts."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The amount kept on account when the payment was recorded, or the credit note's total."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "What is left to apply now (applications waiting for approval reserve theirs)."
          }
        },
        "type": "object",
        "required": [
          "source",
          "id",
          "number",
          "kind",
          "party_id",
          "party_code",
          "party",
          "date",
          "currency",
          "amount",
          "open"
        ],
        "title": "OpenCredit",
        "description": "A payment's amount on account, or a credit note's open amount, that can still be applied."
      },
      "OperatorGoogleLogin": {
        "properties": {
          "credential": {
            "type": "string",
            "minLength": 1,
            "title": "Credential",
            "description": "Google ID token from Google Identity Services."
          }
        },
        "type": "object",
        "required": [
          "credential"
        ],
        "title": "OperatorGoogleLogin",
        "examples": [
          {
            "credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ij..."
          }
        ]
      },
      "OperatorMe": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "`operator:<address>` of a signed-in operator, `platform:<prefix>` of a key."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The operator's address, or the key's name."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "The operator's address; null for a platform key."
          },
          "via": {
            "type": "string",
            "enum": [
              "key",
              "session"
            ],
            "title": "Via",
            "description": "What authenticated the request."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The platform scopes it holds."
          },
          "session_hours": {
            "type": "integer",
            "title": "Session Hours",
            "description": "How long a session lasts from sign-in."
          },
          "idle_minutes": {
            "type": "integer",
            "title": "Idle Minutes",
            "description": "How long a session may sit idle before it ends."
          },
          "workspace_domains": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Workspace Domains",
            "description": "The deployment's own Google Workspace domains: their people sign in with Google and never get a password, so an address there is no customer's administrator."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "email",
          "via",
          "scopes",
          "session_hours",
          "idle_minutes"
        ],
        "title": "OperatorMe"
      },
      "OperatorPasskeyReset": {
        "properties": {
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The address of the person whose passkeys to reset."
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "OperatorPasskeyReset",
        "examples": [
          {
            "email": "erin@example.com"
          }
        ]
      },
      "OperatorPasskeyResetDone": {
        "properties": {
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The person whose passkeys were reset."
          },
          "removed": {
            "type": "integer",
            "title": "Removed",
            "description": "How many passkeys were removed."
          }
        },
        "type": "object",
        "required": [
          "email",
          "removed"
        ],
        "title": "OperatorPasskeyResetDone"
      },
      "OperatorSignedIn": {
        "properties": {
          "status": {
            "type": "string",
            "const": "signed_in",
            "title": "Status",
            "description": "`signed_in`: the `erp_platform_session` cookie was set."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The operator's address."
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "title": "Expires At",
            "description": "When the session ends at the latest (ISO 8601, UTC)."
          }
        },
        "type": "object",
        "required": [
          "status",
          "email",
          "expires_at"
        ],
        "title": "OperatorSignedIn"
      },
      "OpportunityInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity whose pipeline the deal is in."
          },
          "title": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Title",
            "description": "What the deal is."
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the customer; omit it for a prospect that is not a customer yet (then `prospect_name` is required)."
          },
          "prospect_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Prospect Name",
            "description": "The prospect's company name."
          },
          "prospect_country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Prospect Country",
            "description": "The prospect's country (ISO 3166-1)."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "The person the deal is with."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "Their e-mail."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "Their phone."
          },
          "kind": {
            "type": "string",
            "enum": [
              "expansion",
              "new_business",
              "renewal"
            ],
            "title": "Kind",
            "description": "`new_business`, `expansion` (more for an existing customer) or `renewal`.",
            "default": "new_business"
          },
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "negotiation",
              "proposal",
              "qualified"
            ],
            "title": "Stage",
            "description": "The open stage it starts at.",
            "default": "lead"
          },
          "probability": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Probability",
            "description": "Percent; omitted: the stage's default (`lead` (10 %), `qualified` (25 %), `proposal` (50 %), `negotiation` (75 %), `won` (100 %) or `lost` (0 %))."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Currency of the amount; omitted: the customer's currency, else the entity's functional currency."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Expected net value of the deal, e.g. `15000.00`.",
            "default": "0"
          },
          "expected_close": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Close",
            "description": "When it should close."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who owns the deal (`GET /v1/people`); omitted: you (a person; a key or an agent: the person behind it). Someone who sees only their own or their team's records names one of those people."
          },
          "source": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where the lead came from."
          },
          "next_step": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Step",
            "description": "What happens next."
          },
          "forecast_category": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "best_case",
                  "commit",
                  "omitted",
                  "pipeline"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Forecast Category",
            "description": "Where the deal counts in the forecast: `commit` (expected to close in its month), `best_case` (could close), `pipeline` (still being worked) or `omitted` (left out of the forecast); null: as the stage says (negotiation commit, proposal best case, lead and qualified pipeline)."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "The person at the customer the deal is with (`GET /v1/contacts?party_id=`); a deal with a prospect names the person in `contact_name` instead."
          },
          "custom": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "integer"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "title"
        ],
        "title": "OpportunityInput",
        "examples": [
          {
            "amount": "15000.00",
            "contact_email": "eva@beispiel.example",
            "contact_name": "Eva Beispiel",
            "currency": "CHF",
            "entity": "CH01",
            "expected_close": "2026-12-15",
            "owner_user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
            "prospect_country": "DE",
            "prospect_name": "Beispiel GmbH",
            "source": "Trade fair",
            "title": "Platform for 25 seats"
          },
          {
            "amount": "6000.00",
            "entity": "CH01",
            "kind": "expansion",
            "party": "C-CH",
            "stage": "proposal",
            "title": "Ten more seats"
          }
        ]
      },
      "OpportunityOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Opportunity id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "`OPP-000001`, per entity."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the deal is."
          },
          "party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Id",
            "description": "The customer's id; null for a prospect."
          },
          "party_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Code",
            "description": "The customer's code."
          },
          "party_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Name",
            "description": "The customer's name."
          },
          "prospect_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Prospect Name",
            "description": "The prospect's company name."
          },
          "prospect_country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Prospect Country",
            "description": "The prospect's country."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "The person the deal is with."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "Their e-mail."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "Their phone."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "The contact at the customer the deal is with; `contact_name`, `contact_email` and `contact_phone` are then the contact's (empty once it is erased)."
          },
          "kind": {
            "type": "string",
            "enum": [
              "expansion",
              "new_business",
              "renewal"
            ],
            "title": "Kind",
            "description": "`new_business`, `expansion` or `renewal`."
          },
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "lost",
              "negotiation",
              "proposal",
              "qualified",
              "won"
            ],
            "title": "Stage",
            "description": "The stage."
          },
          "probability": {
            "type": "integer",
            "title": "Probability",
            "description": "Percent."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the amounts."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Expected net value."
          },
          "weighted_amount": {
            "type": "string",
            "title": "Weighted Amount",
            "description": "`amount` x `probability`, rounded to the cent."
          },
          "expected_close": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Close",
            "description": "When it should close."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who owns the deal."
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where the lead came from."
          },
          "next_step": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Step",
            "description": "What happens next."
          },
          "lost_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lost Reason",
            "description": "Why it was lost."
          },
          "closed_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed On",
            "description": "The day it was won or lost."
          },
          "forecast_category": {
            "type": "string",
            "enum": [
              "best_case",
              "closed",
              "commit",
              "omitted",
              "pipeline"
            ],
            "title": "Forecast Category",
            "description": "Where it counts in the forecast: `closed` (won), `omitted` (lost or left out), `commit`, `best_case` or `pipeline`."
          },
          "forecast_category_set": {
            "type": "boolean",
            "title": "Forecast Category Set",
            "description": "True when its owner chose the category; false when it follows the stage."
          },
          "custom": {
            "additionalProperties": true,
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "subscription_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subscription Id",
            "description": "A renewal deal's subscription: the deal was opened when its renewal fell due, and is won or lost with the renewal (docs/erp/recurring-revenue.md)."
          },
          "subscription_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subscription Number",
            "description": "Its number."
          },
          "renewal_term_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Renewal Term Start",
            "description": "The first day of the term the deal renews."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "title",
          "party_id",
          "party_code",
          "party_name",
          "prospect_name",
          "prospect_country",
          "contact_name",
          "contact_email",
          "contact_phone",
          "kind",
          "stage",
          "probability",
          "currency",
          "amount",
          "weighted_amount",
          "expected_close",
          "owner",
          "source",
          "next_step",
          "lost_reason",
          "closed_on",
          "forecast_category",
          "forecast_category_set",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "OpportunityOut",
        "examples": [
          {
            "amount": "15000.00",
            "contact_email": "eva@beispiel.example",
            "contact_name": "Eva Beispiel",
            "created_at": "2026-10-04T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "custom": {},
            "entity": "CH01",
            "expected_close": "2026-12-15",
            "forecast_category": "best_case",
            "forecast_category_set": false,
            "id": "3f6a7b8c-9d0e-4f1a-8b2c-3d4e5f6a7b8c",
            "kind": "new_business",
            "next_step": "Demo on 20 October",
            "number": "OPP-000001",
            "owner": {
              "email": "alice@example.com",
              "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "name": "Alice"
            },
            "probability": 50,
            "prospect_country": "DE",
            "prospect_name": "Beispiel GmbH",
            "source": "Trade fair",
            "stage": "proposal",
            "title": "Platform for 25 seats",
            "weighted_amount": "7500.00"
          }
        ]
      },
      "OpportunityUpdate": {
        "properties": {
          "title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Title",
            "description": "New title."
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the customer, e.g. once the prospect is set up as one."
          },
          "prospect_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Prospect Name",
            "description": "`\"\"` clears."
          },
          "prospect_country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^([A-Z]{2})?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Prospect Country",
            "description": "`\"\"` clears."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "`\"\"` clears."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "`\"\"` clears."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 50
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "`\"\"` clears."
          },
          "kind": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "expansion",
                  "new_business",
                  "renewal"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Kind",
            "description": "New kind."
          },
          "probability": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Probability",
            "description": "Percent (an open deal only)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "New currency."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "New expected value."
          },
          "expected_close": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Close",
            "description": "New close date."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "New owner; null clears. Someone who sees only their own or their team's records hands a deal only to one of those people."
          },
          "source": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "`\"\"` clears."
          },
          "next_step": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Step",
            "description": "`\"\"` clears."
          },
          "forecast_category": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "best_case",
                  "commit",
                  "omitted",
                  "pipeline"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Forecast Category",
            "description": "An open deal: where it counts in the forecast, `commit` (expected to close in its month), `best_case` (could close), `pipeline` (still being worked) or `omitted` (left out of the forecast); null: as the stage says (negotiation commit, proposal best case, lead and qualified pipeline) (null clears the choice)."
          },
          "contact_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "string",
                "const": ""
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Id",
            "description": "The person at the customer the deal is with; `\"\"` clears."
          },
          "custom": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    },
                    {
                      "type": "integer"
                    },
                    {
                      "type": "boolean"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          }
        },
        "type": "object",
        "title": "OpportunityUpdate",
        "examples": [
          {
            "amount": "18000.00",
            "expected_close": "2027-01-31"
          },
          {
            "next_step": "Send the contract",
            "party": "C-DE"
          }
        ]
      },
      "OrderBillOut": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the bill."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Number of the bill; null before it is posted."
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number",
            "description": "The vendor's own invoice number."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Status of the bill (`draft`, `pending_approval`, `posted`, `rejected`, `void`)."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Date of the bill."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the bill."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Gross total of the bill, a decimal string."
          },
          "match_status": {
            "type": "string",
            "title": "Match Status",
            "description": "`matched`, `variance` or `unmatched`."
          },
          "payment_block": {
            "type": "boolean",
            "title": "Payment Block",
            "description": "True while an unapproved variance blocks payment of the bill."
          },
          "review": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Review",
            "description": "Paid, but receipts now disagree: why."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "external_number",
          "status",
          "document_date",
          "currency",
          "total",
          "match_status",
          "payment_block"
        ],
        "title": "OrderBillOut",
        "description": "A bill matched to the order and how it matched."
      },
      "OrderCard": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the purchase order."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Order number, e.g. `PO-2026-000001`, from a sequence per entity and year."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `open`, `partially_received`, `partially_invoiced`, `closed` (received and invoiced, or closed for the rest) or `cancelled`."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Vendor code."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "Name of the vendor."
          },
          "vendor_id": {
            "type": "string",
            "format": "uuid",
            "title": "Vendor Id",
            "description": "Id of the vendor."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the order."
          },
          "order_date": {
            "type": "string",
            "format": "date",
            "title": "Order Date",
            "description": "Date of the order."
          },
          "expected_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Date",
            "description": "Expected delivery date; null when none."
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "Your own reference for the order; null when none."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Expected net total of all lines, a decimal string."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the order was created (UTC)."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "Raised on every change; the ETag names it."
          },
          "payment_terms_days": {
            "type": "integer",
            "title": "Payment Terms Days",
            "description": "Payment terms in days."
          },
          "delivery_address": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Address",
            "description": "Delivery address; null when none."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text on the order."
          },
          "cancel_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancel Reason",
            "description": "Why the order was cancelled; null otherwise."
          },
          "close_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Close Reason",
            "description": "Why the order was closed for the rest (short close); null otherwise."
          },
          "closed_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed By",
            "description": "Who closed the order for the rest; null otherwise."
          },
          "closed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed At",
            "description": "When it was closed for the rest (UTC); null otherwise."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created the order (`type`, `id`, `name`)."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved the order; null until approved."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When it was approved (UTC)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The pending approval request, if any."
          },
          "refusal": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/OrderRefusal"
              },
              {
                "type": "null"
              }
            ],
            "description": "A draft whose last approval request was refused: who refused it, when and why. null otherwise (also once it is submitted again)."
          },
          "received_amount": {
            "type": "string",
            "title": "Received Amount",
            "description": "Received quantities at the order prices."
          },
          "invoiced_amount": {
            "type": "string",
            "title": "Invoiced Amount",
            "description": "Net amount invoiced so far on the bills of the order, less what posted credit notes of those bills credited."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/OrderLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines with ordered, received and invoiced quantities."
          },
          "receipts": {
            "items": {
              "$ref": "#/components/schemas/ReceiptOut"
            },
            "type": "array",
            "title": "Receipts",
            "description": "The receipts, oldest first."
          },
          "bills": {
            "items": {
              "$ref": "#/components/schemas/OrderBillOut"
            },
            "type": "array",
            "title": "Bills"
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status",
          "vendor",
          "vendor_name",
          "vendor_id",
          "currency",
          "order_date",
          "expected_date",
          "buyer_reference",
          "net_total",
          "created_at",
          "version",
          "payment_terms_days",
          "delivery_address",
          "notes",
          "cancel_reason",
          "created_by",
          "approved_by",
          "approved_at",
          "approval_id",
          "received_amount",
          "invoiced_amount",
          "lines",
          "receipts",
          "bills"
        ],
        "title": "OrderCard"
      },
      "OrderGrniLine": {
        "properties": {
          "line_id": {
            "type": "string",
            "format": "uuid",
            "title": "Line Id",
            "description": "Id of the order line."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Number of the order line."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description of the order line."
          },
          "item": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item",
            "description": "Code of the stock item the line buys; null for none."
          },
          "last_receipt": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Receipt",
            "description": "Day of the line's last receipt (a write-off is dated no earlier)."
          },
          "received_quantity": {
            "type": "string",
            "title": "Received Quantity",
            "description": "Received, from the posted receipts."
          },
          "received_value": {
            "type": "string",
            "title": "Received Value",
            "description": "Their receipt value (functional currency)."
          },
          "billed_quantity": {
            "type": "string",
            "title": "Billed Quantity",
            "description": "Billed on posted bills, net of the quantities credit notes credited."
          },
          "cleared_quantity": {
            "type": "string",
            "title": "Cleared Quantity",
            "description": "What bills cleared of what was received."
          },
          "cleared_value": {
            "type": "string",
            "title": "Cleared Value",
            "description": "The receipt value of what was cleared."
          },
          "written_off_quantity": {
            "type": "string",
            "title": "Written Off Quantity",
            "description": "Written off as never to be billed (posted or waiting for approval)."
          },
          "written_off_value": {
            "type": "string",
            "title": "Written Off Value",
            "description": "The receipt value written off."
          },
          "open_quantity": {
            "type": "string",
            "title": "Open Quantity",
            "description": "Received, not billed, not written off."
          },
          "open_value": {
            "type": "string",
            "title": "Open Value",
            "description": "Its value: the line's GR/IR balance."
          },
          "billed_after_write_off": {
            "type": "string",
            "title": "Billed After Write Off",
            "description": "Billed after the line was written off, so nothing to clear: the bill's cost offsets the write-off on its account (zero for none)."
          }
        },
        "type": "object",
        "required": [
          "line_id",
          "line_no",
          "description",
          "item",
          "last_receipt",
          "received_quantity",
          "received_value",
          "billed_quantity",
          "cleared_quantity",
          "cleared_value",
          "written_off_quantity",
          "written_off_value",
          "open_quantity",
          "open_value",
          "billed_after_write_off"
        ],
        "title": "OrderGrniLine"
      },
      "OrderGrniOut": {
        "properties": {
          "order_id": {
            "type": "string",
            "format": "uuid",
            "title": "Order Id",
            "description": "Id of the purchase order."
          },
          "order_number": {
            "type": "string",
            "title": "Order Number",
            "description": "Number of the purchase order."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency of the entity."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/OrderGrniLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "Per order line."
          },
          "open_value": {
            "type": "string",
            "title": "Open Value",
            "description": "The order's GR/IR balance (received, not billed)."
          },
          "write_off_waiting": {
            "type": "boolean",
            "title": "Write Off Waiting",
            "description": "A write-off of the order waits for a second person to approve it."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "order_number",
          "currency",
          "lines",
          "open_value",
          "write_off_waiting"
        ],
        "title": "OrderGrniOut"
      },
      "OrderInput": {
        "properties": {
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Vendor code or id; it must be active."
          },
          "order_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Date",
            "description": "Date of the order (ISO 8601, e.g. `2026-09-01`); default today where the company is."
          },
          "expected_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Date",
            "description": "Expected delivery; not before the order date."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Vendor's."
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "Your own reference for the order, e.g. a project or requisition number (up to 100 characters); searchable with `q`."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Vendor's."
          },
          "delivery_address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DeliveryAddress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the goods are delivered; omit for the entity's own address."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text kept on the order (up to 2000 characters)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/OrderLineInput"
            },
            "type": "array",
            "maxItems": 500,
            "minItems": 1,
            "title": "Lines",
            "description": "The order lines, 1 to 500. Each is matched later against the bill's lines."
          }
        },
        "type": "object",
        "required": [
          "vendor",
          "lines"
        ],
        "title": "OrderInput",
        "examples": [
          {
            "buyer_reference": "REQ-2026-17",
            "expected_date": "2026-09-10",
            "lines": [
              {
                "account": "4000",
                "description": "Office chairs",
                "line_type": "goods",
                "quantity": "10",
                "unit_price": "100.00"
              }
            ],
            "order_date": "2026-09-01",
            "vendor": "V-BM"
          }
        ]
      },
      "OrderInvoiceOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the invoice (`GET /v1/documents/{id}`)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number; null before it is posted."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `posted`, `rejected` or `void`."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Day of the invoice."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Net total of the invoice."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total including VAT."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status",
          "document_date",
          "net_total",
          "total"
        ],
        "title": "OrderInvoiceOut",
        "description": "An invoice made from the order."
      },
      "OrderLineInput": {
        "properties": {
          "description": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Description",
            "description": "What is ordered (1 to 500 characters); a bill line is paired with the order line by this text when it names no order line."
          },
          "line_type": {
            "type": "string",
            "enum": [
              "goods",
              "services"
            ],
            "title": "Line Type",
            "description": "`goods` (default) or `services`.",
            "default": "goods"
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Expense or asset account code."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Quantity",
            "description": "Ordered quantity, a decimal string above 0 with at most 6 decimals, e.g. `10`."
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Unit Price",
            "description": "Expected net unit price."
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "exempt",
              "parking",
              "reduced",
              "special",
              "standard",
              "super_reduced",
              "zero"
            ],
            "title": "Rate Type",
            "description": "The tax code of the line.",
            "default": "standard"
          },
          "tax_category": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Category",
            "description": "One of the categories of the rate (`GET /v1/entities/{entity}/vat-rate-types`), e.g. `books`: it chooses the rate where the rate type has several (France reduced: 5.5 % or 10 %) and names the kind of an exempt supply (`insurance`). Omit for none."
          },
          "requires_receipt": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Requires Receipt",
            "description": "Bills are matched 3-way against received quantities (default: goods yes, services no); otherwise 2-way against the ordered quantity."
          },
          "item": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Item",
            "description": "A stock item of the order's entity the line buys (its product's code or id); the quantity is in the item's unit. Received goods then enter stock at the line's net price. Such a line is goods and needs a receipt."
          }
        },
        "type": "object",
        "required": [
          "description",
          "quantity",
          "unit_price"
        ],
        "title": "OrderLineInput"
      },
      "OrderLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the order line."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Line number, from 1."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What is ordered."
          },
          "line_type": {
            "type": "string",
            "title": "Line Type",
            "description": "`goods` or `services`."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Account code."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Ordered quantity, a decimal string."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Expected net unit price, a decimal string."
          },
          "net_amount": {
            "type": "string",
            "title": "Net Amount",
            "description": "Expected net amount."
          },
          "rate_type": {
            "type": "string",
            "title": "Rate Type",
            "description": "The tax code."
          },
          "tax_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Category",
            "description": "Named tax category; null when the rate type decides."
          },
          "requires_receipt": {
            "type": "boolean",
            "title": "Requires Receipt",
            "description": "3-way match against received quantities."
          },
          "received_quantity": {
            "type": "string",
            "title": "Received Quantity",
            "description": "Quantity received so far, from the receipts (not those rejected)."
          },
          "invoiced_quantity": {
            "type": "string",
            "title": "Invoiced Quantity",
            "description": "Quantity on the bills matched to the order (bills that count), less what posted credit notes of those bills credited of the line (credit note lines that name the bill line, `credits_line`)."
          },
          "invoiced_amount": {
            "type": "string",
            "title": "Invoiced Amount",
            "description": "Net amount on those bills less those credit notes, a decimal string."
          },
          "closed_quantity": {
            "type": "string",
            "title": "Closed Quantity",
            "description": "Quantity closed when the order was closed for the rest: no longer expected, neither received nor invoiced.",
            "default": "0"
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Id",
            "description": "The stock item the line buys (its product's id): received goods enter stock; null for any other line."
          },
          "item": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item",
            "description": "Code of that stock item's product; null for any other line."
          }
        },
        "type": "object",
        "required": [
          "id",
          "line_no",
          "description",
          "line_type",
          "account",
          "quantity",
          "unit_price",
          "net_amount",
          "rate_type",
          "tax_category",
          "requires_receipt",
          "received_quantity",
          "invoiced_quantity",
          "invoiced_amount"
        ],
        "title": "OrderLineOut"
      },
      "OrderOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the purchase order."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Order number, e.g. `PO-2026-000001`, from a sequence per entity and year."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `open`, `partially_received`, `partially_invoiced`, `closed` (received and invoiced, or closed for the rest) or `cancelled`."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Vendor code."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "Name of the vendor."
          },
          "vendor_id": {
            "type": "string",
            "format": "uuid",
            "title": "Vendor Id",
            "description": "Id of the vendor."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the order."
          },
          "order_date": {
            "type": "string",
            "format": "date",
            "title": "Order Date",
            "description": "Date of the order."
          },
          "expected_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Date",
            "description": "Expected delivery date; null when none."
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "Your own reference for the order; null when none."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Expected net total of all lines, a decimal string."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the order was created (UTC)."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "Raised on every change; the ETag names it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status",
          "vendor",
          "vendor_name",
          "vendor_id",
          "currency",
          "order_date",
          "expected_date",
          "buyer_reference",
          "net_total",
          "created_at",
          "version"
        ],
        "title": "OrderOut"
      },
      "OrderRefusal": {
        "properties": {
          "decided_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Decided By",
            "description": "Who refused it (`type`, `id`, `name`)."
          },
          "decided_at": {
            "type": "string",
            "format": "date-time",
            "title": "Decided At",
            "description": "When it was refused (UTC)."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "The reason given with the refusal; null when none."
          }
        },
        "type": "object",
        "required": [
          "decided_by",
          "decided_at",
          "comment"
        ],
        "title": "OrderRefusal",
        "description": "The approval a second person refused, which returned the order to draft."
      },
      "OrderUpdate": {
        "properties": {
          "vendor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor",
            "description": "New vendor code or id; cannot be cleared."
          },
          "order_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Order Date",
            "description": "Date of the order (ISO 8601, e.g. `2026-09-01`). Omit to keep the current value."
          },
          "expected_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Expected Date",
            "description": "Expected delivery date (ISO 8601); not before `order_date`. Omit when unknown. Omit to keep the current value."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code of the order, e.g. `CHF`. Default: the vendor's currency. Omit to keep the current value."
          },
          "buyer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Buyer Reference",
            "description": "Your own reference for the order, e.g. a project or requisition number (up to 100 characters); searchable with `q`. Omit to keep the current value."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Payment terms in days, 0 to 365. Default: the vendor's. Omit to keep the current value."
          },
          "delivery_address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DeliveryAddress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where the goods are delivered; omit for the entity's own address. Omit to keep the current value."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text kept on the order (up to 2000 characters). Omit to keep the current value."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/OrderLineInput"
                },
                "type": "array",
                "maxItems": 500,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "New lines; they replace every line. Omit to keep them."
          }
        },
        "type": "object",
        "title": "OrderUpdate",
        "description": "Changes to a draft; omitted fields keep their value, ``lines`` replaces every line.",
        "examples": [
          {
            "expected_date": "2026-09-12",
            "notes": "Deliver to the reception desk."
          }
        ]
      },
      "OrganizationDetail": {
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "Id (uuid) of the organization."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The organization's name."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "suspended"
            ],
            "title": "Status",
            "description": "`active`, or `suspended`: the organization can read but not change anything until it is reactivated."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the organization was created (ISO 8601, UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it, as an actor object (`type`, `id`, `name`): a platform key (`platform:<prefix>`) or the command line."
          },
          "status_changed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Changed At",
            "description": "When it was last suspended or reactivated; null if never."
          },
          "status_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Reason",
            "description": "Why it was last suspended or reactivated; null if never."
          },
          "kind": {
            "type": "string",
            "enum": [
              "customer",
              "demo"
            ],
            "title": "Kind",
            "description": "`customer`: its books are kept for the statutory period and never deleted. `demo`: made to be looked at. An operator deletes either in the portal (`POST /v1/platform/organizations/{org_id}/delete`, ADR-0042).",
            "default": "customer"
          },
          "copy_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Copy Of",
            "description": "For a test copy (always a `demo`), the organization it was made from (ADR-0039); null for every other organization."
          },
          "remove_requested_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remove Requested At",
            "description": "When its deletion was asked for (`POST /v1/platform/organizations/{org_id}/delete`, or the removal of a test copy): nobody reaches it from then on, and an operator can undo it until `delete_after` (ADR-0042). Null otherwise."
          },
          "delete_after": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delete After",
            "description": "When the owner's job may delete it for good: an hour after `remove_requested_at`. It runs every hour and at every deploy, so the organization is gone within the hour after this. Until then an operator can undo the deletion (`POST /v1/platform/organizations/{org_id}/undo-delete`). Null when no deletion was asked for."
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/OrganizationUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "Counts and last activity; null unless the list was asked with `usage=true` (each organization is read in a transaction of its own, so it is not free)."
          },
          "entities": {
            "items": {
              "$ref": "#/components/schemas/EntitySummary"
            },
            "type": "array",
            "title": "Entities",
            "description": "Its legal entities."
          },
          "users": {
            "items": {
              "$ref": "#/components/schemas/OrganizationUser"
            },
            "type": "array",
            "title": "Users",
            "description": "Its people, by address."
          },
          "evidence": {
            "$ref": "#/components/schemas/OrganizationEvidence",
            "description": "The evidence of use."
          }
        },
        "type": "object",
        "required": [
          "org_id",
          "name",
          "status",
          "created_at",
          "created_by",
          "status_changed_at",
          "status_reason",
          "entities",
          "users",
          "evidence"
        ],
        "title": "OrganizationDetail",
        "description": "One organization as the operator sees it: master data and counts, never the books."
      },
      "OrganizationEvidence": {
        "properties": {
          "users": {
            "type": "integer",
            "title": "Users",
            "description": "People of the organization."
          },
          "users_not_administrators": {
            "type": "integer",
            "title": "Users Not Administrators",
            "description": "People who are not administrators."
          },
          "users_invited_by_people": {
            "type": "integer",
            "title": "Users Invited By People",
            "description": "People invited by a person or an API key, not by the demo seed, the system or the platform: the initial administrators are not counted."
          },
          "users_signed_in": {
            "type": "integer",
            "title": "Users Signed In",
            "description": "People who have signed in at least once."
          },
          "journal_entries": {
            "type": "integer",
            "title": "Journal Entries",
            "description": "Journal entries."
          },
          "journal_entries_not_by_the_seed": {
            "type": "integer",
            "title": "Journal Entries Not By The Seed",
            "description": "Journal entries created by an actor that is neither `demo:*` nor `system:*`."
          },
          "documents": {
            "type": "integer",
            "title": "Documents",
            "description": "Invoices and bills."
          },
          "documents_not_by_the_seed": {
            "type": "integer",
            "title": "Documents Not By The Seed",
            "description": "Invoices and bills created by such an actor."
          },
          "document_dispatches": {
            "type": "integer",
            "title": "Document Dispatches",
            "description": "Invoices handed to a customer."
          },
          "issued_outputs_archived": {
            "type": "integer",
            "title": "Issued Outputs Archived",
            "description": "Files archived as issued."
          },
          "bank_statements": {
            "type": "integer",
            "title": "Bank Statements",
            "description": "Bank statements imported."
          },
          "first_posting": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Posting",
            "description": "Date of the first posted entry; null if none."
          },
          "last_posting": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Posting",
            "description": "Date of the last posted entry; null if none."
          },
          "customer_grade": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Customer Grade",
            "description": "Why it looks like a customer's organization; empty when it looks like a demo."
          }
        },
        "type": "object",
        "required": [
          "users",
          "users_not_administrators",
          "users_invited_by_people",
          "users_signed_in",
          "journal_entries",
          "journal_entries_not_by_the_seed",
          "documents",
          "documents_not_by_the_seed",
          "document_dispatches",
          "issued_outputs_archived",
          "bank_statements",
          "first_posting",
          "last_posting",
          "customer_grade"
        ],
        "title": "OrganizationEvidence",
        "description": "The signs of real use that decide whether an organization may be marked as a demo\n(`org_activity`, ADR-0022). A non-empty `customer_grade` means it looks like a customer."
      },
      "OrganizationOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the organization."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The organization's name."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the organization was created (ISO 8601, UTC)."
          },
          "approval_policy": {
            "type": "string",
            "enum": [
              "default",
              "organization"
            ],
            "title": "Approval Policy",
            "description": "Whether the default approval policy or the organization's own applies (GET /v1/approval-policy)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "created_at",
          "approval_policy"
        ],
        "title": "OrganizationOut"
      },
      "OrganizationSummary": {
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "Id (uuid) of the organization."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The organization's name."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "suspended"
            ],
            "title": "Status",
            "description": "`active`, or `suspended`: the organization can read but not change anything until it is reactivated."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the organization was created (ISO 8601, UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it, as an actor object (`type`, `id`, `name`): a platform key (`platform:<prefix>`) or the command line."
          },
          "status_changed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Changed At",
            "description": "When it was last suspended or reactivated; null if never."
          },
          "status_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Reason",
            "description": "Why it was last suspended or reactivated; null if never."
          },
          "kind": {
            "type": "string",
            "enum": [
              "customer",
              "demo"
            ],
            "title": "Kind",
            "description": "`customer`: its books are kept for the statutory period and never deleted. `demo`: made to be looked at. An operator deletes either in the portal (`POST /v1/platform/organizations/{org_id}/delete`, ADR-0042).",
            "default": "customer"
          },
          "copy_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Copy Of",
            "description": "For a test copy (always a `demo`), the organization it was made from (ADR-0039); null for every other organization."
          },
          "remove_requested_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remove Requested At",
            "description": "When its deletion was asked for (`POST /v1/platform/organizations/{org_id}/delete`, or the removal of a test copy): nobody reaches it from then on, and an operator can undo it until `delete_after` (ADR-0042). Null otherwise."
          },
          "delete_after": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delete After",
            "description": "When the owner's job may delete it for good: an hour after `remove_requested_at`. It runs every hour and at every deploy, so the organization is gone within the hour after this. Until then an operator can undo the deletion (`POST /v1/platform/organizations/{org_id}/undo-delete`). Null when no deletion was asked for."
          },
          "usage": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/OrganizationUsage"
              },
              {
                "type": "null"
              }
            ],
            "description": "Counts and last activity; null unless the list was asked with `usage=true` (each organization is read in a transaction of its own, so it is not free)."
          }
        },
        "type": "object",
        "required": [
          "org_id",
          "name",
          "status",
          "created_at",
          "created_by",
          "status_changed_at",
          "status_reason"
        ],
        "title": "OrganizationSummary",
        "description": "A row of the operator's list: the lifecycle, and the usage when it was asked for."
      },
      "OrganizationSwitch": {
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "Id (uuid) of the organization to switch to, from `GET /v1/auth/organizations`."
          }
        },
        "type": "object",
        "required": [
          "org_id"
        ],
        "title": "OrganizationSwitch",
        "examples": [
          {
            "org_id": "3f0c2a9e-5b7d-4e1a-9c8b-2d6f4a1e7b30"
          }
        ]
      },
      "OrganizationUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The new name, 1 to 200 characters; omit to change nothing."
          }
        },
        "type": "object",
        "title": "OrganizationUpdate",
        "examples": [
          {
            "name": "Demo Group AG"
          }
        ]
      },
      "OrganizationUsage": {
        "properties": {
          "entities": {
            "type": "integer",
            "title": "Entities",
            "description": "Number of legal entities."
          },
          "users": {
            "type": "integer",
            "title": "Users",
            "description": "Number of people (invited, active or disabled)."
          },
          "entries": {
            "type": "integer",
            "title": "Entries",
            "description": "Number of journal entries, drafts and posted."
          },
          "documents": {
            "type": "integer",
            "title": "Documents",
            "description": "Number of invoices, bills and credit notes."
          },
          "last_activity_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Activity At",
            "description": "The last event in the organization's audit trail that a person, a key or the demo seed caused (what the platform does inside it does not count); null if none."
          },
          "last_sign_in_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Sign In At",
            "description": "The last sign-in of any of its people; null if nobody ever signed in."
          }
        },
        "type": "object",
        "required": [
          "entities",
          "users",
          "entries",
          "documents",
          "last_activity_at",
          "last_sign_in_at"
        ],
        "title": "OrganizationUsage",
        "description": "What an organization has been used for: counts only, never a ledger line or an amount."
      },
      "OrganizationUser": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the user."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The sign-in address, lower case."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Display name; null until set."
          },
          "role": {
            "type": "string",
            "title": "Role",
            "description": "`admin`, `controller`, `accountant`, `auditor` or `viewer` when the scopes are exactly that preset, else `custom`."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`invited` (never signed in), `active` or `disabled`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the user was invited (ISO 8601, UTC)."
          },
          "last_login_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Login At",
            "description": "The last sign-in; null if never."
          }
        },
        "type": "object",
        "required": [
          "id",
          "email",
          "name",
          "role",
          "status",
          "created_at",
          "last_login_at"
        ],
        "title": "OrganizationUser"
      },
      "Outcome": {
        "properties": {
          "line_id": {
            "type": "string",
            "format": "uuid",
            "title": "Line Id",
            "description": "Id (uuid) of the bank line."
          },
          "booking_date": {
            "type": "string",
            "format": "date",
            "title": "Booking Date",
            "description": "Booking date of the line (ISO 8601)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Signed amount of the bank line in its currency: positive money in, negative money out."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the bank line."
          },
          "counterparty": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty",
            "description": "Counterparty name on the line; null if none."
          },
          "action": {
            "type": "string",
            "enum": [
              "leave",
              "match",
              "post"
            ],
            "title": "Action",
            "description": "What the model proposed: `match`, `post` or `leave`."
          },
          "status": {
            "type": "string",
            "enum": [
              "left",
              "pending_approval",
              "posted",
              "proposed",
              "rejected"
            ],
            "title": "Status",
            "description": "`pending_approval` (applied, waits for a person), `posted`, `proposed` (valid but not applied), `rejected` (failed validation) or `left`."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "A sentence on what happened or why not."
          },
          "confidence": {
            "type": "number",
            "title": "Confidence",
            "description": "0 to 1: how sure the model was."
          },
          "reasons": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Reasons",
            "description": "The model's reasons."
          },
          "allocations": {
            "items": {
              "$ref": "#/components/schemas/AllocationInput-Output"
            },
            "type": "array",
            "title": "Allocations",
            "description": "For a match: the documents and amounts settled."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "For a post: the counter account code; null otherwise."
          },
          "document_ids": {
            "additionalProperties": {
              "type": "string",
              "format": "uuid"
            },
            "type": "object",
            "title": "Document Ids",
            "description": "For a match: the id of each document in `allocations`, by its number."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "Id (uuid) of the approval request when one was created; else null."
          }
        },
        "type": "object",
        "required": [
          "line_id",
          "booking_date",
          "amount",
          "currency",
          "counterparty",
          "action",
          "status",
          "detail",
          "confidence",
          "reasons"
        ],
        "title": "Outcome"
      },
      "OutcomeOut": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "The outcome, e.g. `bank_matched`."
          },
          "area": {
            "type": "string",
            "title": "Area",
            "description": "Its area: `bank`, `payables`, `receivables`, `ledger`, `close`, `tax`, `group`, `sales`."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "The outcome in English, e.g. `The bank is matched`."
          },
          "test": {
            "type": "string",
            "title": "Test",
            "description": "How the system knows it is true, in English."
          },
          "events": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Events",
            "description": "What makes it work at once, in English."
          },
          "enabled": {
            "type": "boolean",
            "title": "Enabled",
            "description": "Whether Autopilot keeps it for this company."
          },
          "acting_for": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acting For",
            "description": "The person whose work its passes count as."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of its notes and questions."
          },
          "options": {
            "additionalProperties": true,
            "type": "object",
            "title": "Options",
            "description": "Its settings, with the defaults filled in."
          },
          "due": {
            "type": "boolean",
            "title": "Due",
            "description": "Something happened that gives it work: a pass comes soon."
          },
          "state": {
            "type": "string",
            "enum": [
              "off",
              "on_track",
              "open",
              "problem",
              "waiting"
            ],
            "title": "State",
            "description": "`off`; `on_track` (nothing open after the last pass); `open` (items open, none waiting for a person); `waiting` (a person's step or question waits); `problem` (the last pass failed)."
          },
          "open": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Open",
            "description": "Items open after the last pass."
          },
          "last_pass": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PassSummary"
              },
              {
                "type": "null"
              }
            ],
            "description": "The latest pass."
          },
          "handoffs": {
            "items": {
              "$ref": "#/components/schemas/Handoff"
            },
            "type": "array",
            "title": "Handoffs",
            "description": "What the latest pass left a person."
          }
        },
        "type": "object",
        "required": [
          "key",
          "area",
          "title",
          "test",
          "events",
          "enabled",
          "acting_for",
          "language",
          "options",
          "due",
          "state",
          "open",
          "last_pass",
          "handoffs"
        ],
        "title": "OutcomeOut"
      },
      "OutcomeSettingInput": {
        "properties": {
          "enabled": {
            "type": "boolean",
            "title": "Enabled",
            "description": "Switch Autopilot on or off for this outcome."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of its notes and questions.",
            "default": "en"
          },
          "options": {
            "additionalProperties": true,
            "type": "object",
            "title": "Options",
            "description": "Its settings: `vendors_paid` takes `days_before_due` (pay a bill this many days before it is due, 0 to 30, default 2); the others take none."
          }
        },
        "additionalProperties": false,
        "type": "object",
        "required": [
          "enabled"
        ],
        "title": "OutcomeSettingInput",
        "examples": [
          {
            "enabled": true,
            "language": "en"
          }
        ]
      },
      "Overdue": {
        "properties": {
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Number of overdue open documents."
          },
          "totals_by_currency": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Totals By Currency",
            "description": "Overdue open amount per document currency (ISO 4217 code to decimal string)."
          }
        },
        "type": "object",
        "required": [
          "count",
          "totals_by_currency"
        ],
        "title": "Overdue"
      },
      "Overview": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "entity_name": {
            "type": "string",
            "title": "Entity Name",
            "description": "Name of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; the amounts below are in it."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day the figures are computed for (ISO 8601)."
          },
          "period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period",
            "description": "Label of the regular period containing `as_of`, e.g. `2026-09`; null when none."
          },
          "period_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period Status",
            "description": "`open` or `closed`; null when no period contains `as_of`."
          },
          "pending_approvals": {
            "type": "integer",
            "title": "Pending Approvals",
            "description": "Approval requests of the entity waiting for a decision."
          },
          "pending_for_me": {
            "type": "integer",
            "title": "Pending For Me",
            "description": "Of `pending_approvals`, those the four-eyes principle leaves the caller free to decide: not requested, created, prepared or submitted by the caller (whichever key or session); 0 for a key the system issued. The approve scope and the approval policy are not asked. The length of `GET /v1/approvals?entity={entity}&for_me=true`."
          },
          "draft_entries": {
            "type": "integer",
            "title": "Draft Entries",
            "description": "Journal entries of the entity still in `draft`."
          },
          "unmatched_bank_lines": {
            "type": "integer",
            "title": "Unmatched Bank Lines",
            "description": "Bank statement lines not yet matched or posted."
          },
          "unappropriated_years": {
            "type": "integer",
            "title": "Unappropriated Years",
            "description": "Closed fiscal years whose general meeting is overdue while part of the result is still unappropriated (a Swiss entity, six months after the year end): the count the cue shows, and the length of `GET /v1/entities/{entity}/fiscal-years?unappropriated=true`.",
            "default": 0,
            "examples": [
              1
            ]
          },
          "recurring_due": {
            "type": "integer",
            "title": "Recurring Due",
            "description": "Active recurring invoices with a due date on or before `as_of`: the count the cue shows, and the length of `GET /v1/recurring-invoices?entity={entity}&due_through={as_of}`. A run (`POST /v1/recurring-invoices/run`) makes their invoices.",
            "default": 0
          },
          "recurring_journals_due": {
            "type": "integer",
            "title": "Recurring Journals Due",
            "description": "Active recurring journals with a due date on or before `as_of`: the count the cue shows, and the length of `GET /v1/recurring-journals?entity={entity}&due_through={as_of}`. A run (`POST /v1/recurring-journals/run`) posts their entries.",
            "default": 0
          },
          "periods_in_close": {
            "type": "integer",
            "title": "Periods In Close",
            "description": "Regular periods that ended before `as_of` and are still open, from the one of the entity's first posted entry on (a period of a fiscal year whose close is posted counts as closed): the cue \"periods in close\", each with its close status at `GET /v1/periods/{period_id}/close-status`. A new company's months before its first entry are not counted.",
            "default": 0
          },
          "vat_returns_due_soon": {
            "type": "integer",
            "title": "Vat Returns Due Soon",
            "description": "VAT returns of this and last year not yet final and due to be filed and paid within 14 days of `as_of` (`due_status` `due_soon` in `GET /v1/entities/{entity}/vat-periods`); 0 for an entity without a VAT number.",
            "default": 0
          },
          "vat_returns_overdue": {
            "type": "integer",
            "title": "Vat Returns Overdue",
            "description": "VAT returns of this and last year past their due date and not final (`due_status` `overdue`), from the start of the entity's books.",
            "default": 0
          },
          "overdue_receivables": {
            "$ref": "#/components/schemas/Overdue",
            "description": "Open customer invoices past their due date."
          },
          "overdue_payables": {
            "$ref": "#/components/schemas/Overdue",
            "description": "Open vendor bills past their due date."
          },
          "cash": {
            "type": "string",
            "title": "Cash",
            "description": "Balance of the cash and bank accounts at `as_of`."
          },
          "revenue_mtd": {
            "type": "string",
            "title": "Revenue Mtd",
            "description": "Revenue from the first of the month of `as_of` through `as_of`."
          },
          "net_income_mtd": {
            "type": "string",
            "title": "Net Income Mtd",
            "description": "Net income from the first of the month of `as_of` through `as_of`."
          },
          "recent_entries": {
            "items": {
              "$ref": "#/components/schemas/RecentEntry"
            },
            "type": "array",
            "title": "Recent Entries",
            "description": "The eight most recently posted entries, newest first."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "entity_name",
          "currency",
          "as_of",
          "period",
          "period_status",
          "pending_approvals",
          "pending_for_me",
          "draft_entries",
          "unmatched_bank_lines",
          "overdue_receivables",
          "overdue_payables",
          "cash",
          "revenue_mtd",
          "net_income_mtd",
          "recent_entries"
        ],
        "title": "Overview"
      },
      "ParsedLine": {
        "properties": {
          "booking_date": {
            "type": "string",
            "format": "date",
            "title": "Booking Date",
            "description": "Day the bank booked it, ISO 8601."
          },
          "value_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value Date",
            "description": "Value day, ISO 8601, if given."
          },
          "amount": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Amount",
            "description": "Signed amount: positive is money in, negative out."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code of the amount."
          },
          "counterparty_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Name",
            "description": "Who paid or was paid."
          },
          "counterparty_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty Iban",
            "description": "The counterparty's IBAN."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Structured reference (QR or ISO 11649) or reference text."
          },
          "end_to_end_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "End To End Id",
            "description": "End-to-end id of a payment file's payment (camt only)."
          },
          "remittance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remittance",
            "description": "The booking or remittance text."
          },
          "bank_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Reference",
            "description": "The bank's own id of the transaction: a later file holding it again skips it."
          },
          "returned": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Returned",
            "description": "On a credit that returns an outgoing payment (camt only: ``RtrInf``, or the bank transaction code ICDT/RRTN), or a debit that returns a direct debit we collected (``RtrInf``, or IDDT/UPDD or IDDT/PRDD), the bank's reason: ``code`` (ISO 20022) and ``text``."
          }
        },
        "type": "object",
        "required": [
          "booking_date",
          "amount",
          "currency"
        ],
        "title": "ParsedLine",
        "description": "One transaction as read from a statement file."
      },
      "PartialRetirementInput": {
        "properties": {
          "percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Percent",
            "description": "The part retired, in percent of the asset's cost (above 0, below 100)."
          },
          "cost": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost",
            "description": "The part retired as an amount of the asset's cost, in the company's currency (below the cost). Give this or `percent`."
          },
          "retirement_date": {
            "type": "string",
            "format": "date",
            "title": "Retirement Date",
            "description": "Day the part leaves, ISO 8601; the entry is dated on it and its period must be open."
          },
          "proceeds": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Proceeds",
            "description": "Net proceeds for the part, without VAT. Default \"0\" (scrapped).",
            "default": "0"
          },
          "proceeds_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proceeds Account",
            "description": "The account the proceeds are debited to, usually the bank account they were paid into. To sell to a customer on an invoice, use `POST /v1/assets/{asset}/sale`."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why, in your own words (kept with the change and shown to the approver)."
          }
        },
        "type": "object",
        "required": [
          "retirement_date"
        ],
        "title": "PartialRetirementInput",
        "examples": [
          {
            "percent": "25",
            "proceeds": "2000.00",
            "proceeds_account": "1020",
            "retirement_date": "2026-10-15"
          }
        ]
      },
      "Party": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "BT-27 / BT-44 / BT-59 / BT-62"
          },
          "trading_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Trading Name",
            "description": "BT-28 / BT-45 / BT-60"
          },
          "identifiers": {
            "items": {
              "$ref": "#/components/schemas/Identifier"
            },
            "type": "array",
            "title": "Identifiers",
            "description": "BT-29 / BT-46"
          },
          "legal_id": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Identifier"
              },
              {
                "type": "null"
              }
            ],
            "description": "BT-30 / BT-47 / BT-61"
          },
          "vat_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Id",
            "description": "BT-31 / BT-48 / BT-63"
          },
          "tax_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Id",
            "description": "BT-32 seller tax registration id"
          },
          "legal_info": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Legal Info",
            "description": "BT-33 additional legal info"
          },
          "electronic_address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Identifier"
              },
              {
                "type": "null"
              }
            ],
            "description": "BT-34 / BT-49"
          },
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PostalAddress"
              },
              {
                "type": "null"
              }
            ],
            "description": "BG-5 / BG-8 / BG-12"
          },
          "contact": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Contact"
              },
              {
                "type": "null"
              }
            ],
            "description": "BG-6 / BG-9"
          }
        },
        "type": "object",
        "title": "Party",
        "description": "Seller (BG-4), buyer (BG-7), payee (BG-10) or seller tax representative (BG-11)."
      },
      "PartyBankAccount": {
        "properties": {
          "iban": {
            "type": "string",
            "maxLength": 42,
            "minLength": 5,
            "title": "Iban",
            "description": "IBAN of the account, 5 to 42 characters; stored without spaces."
          },
          "bic": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{6}[A-Z2-9][A-NP-Z0-9]([A-Z0-9]{3})?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "BIC/SWIFT code of the bank (8 or 11 characters)."
          },
          "label": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Label",
            "description": "Short label for the account, e.g. `QR-IBAN`."
          }
        },
        "type": "object",
        "required": [
          "iban"
        ],
        "title": "PartyBankAccount",
        "description": "A further account of a customer or vendor next to its IBAN, e.g. a QR-IBAN."
      },
      "PartyCard": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the customer or vendor."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`customer` or `vendor`."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The party's short code, e.g. `C-DE`; unique per kind in an entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 subdivision used for tax, if any."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "VAT or UID number."
          },
          "business": {
            "type": "boolean",
            "title": "Business",
            "description": "`true` for a business (B2B), `false` for a private person (B2C)."
          },
          "split_payment": {
            "type": "boolean",
            "title": "Split Payment",
            "description": "Italy: `true` for a customer under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter, e.g. a public body): an Italian company's invoices to it show the VAT, which the customer pays to the State, and the customer owes the net amount.",
            "default": false
          },
          "withholding_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Code",
            "description": "Vendors: the withholding tax code its bills keep back (`IT-RA-20`, `custom`); null for none."
          },
          "withholding_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Rate",
            "description": "Vendors: the withholding rate in percent of a bill's net amount before VAT."
          },
          "vat_unverified": {
            "type": "boolean",
            "title": "Vat Unverified",
            "description": "`true` for a vendor created from a received document whose `vat_number` (recorded as printed) is not a valid Swiss UID or German USt-IdNr; a later change of `vat_number` that passes the check clears it.",
            "default": false
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the party's documents and payments."
          },
          "payment_terms_days": {
            "type": "integer",
            "title": "Payment Terms Days",
            "description": "Days from the document date to the due date."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Contact email address."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "IBAN payments to the party go to, without spaces."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the postal address."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the postal address."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`active`; `draft` until a second person activates it (a draft is neither booked nor paid); `blocked` (no new documents or orders, nothing paid to it; what it pays still settles its open items) or `inactive` (no longer used, no open items).",
            "default": "active"
          },
          "group_entity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Group Entity Id",
            "description": "Id of the entity this customer or vendor is, when it is another entity of the organization (created by an approved intercompany relationship); null for an ordinary customer or vendor. Its documents post to the group accounts (`ic_ar_control`, `ic_ap_control`) and are mirrored in that entity."
          },
          "leitweg_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Leitweg Id",
            "description": "Leitweg-ID of a German public buyer (XRechnung buyer reference)."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "E-invoicing address (EN 16931 BT-34 / BT-49)."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "EAS code of the electronic address, e.g. `EM`."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount (Skonto) percent if paid within the days."
          },
          "cash_discount_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Days",
            "description": "Days within which the cash discount applies."
          },
          "credit_limit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Limit",
            "description": "Customers: the most the customer may owe, in its currency (`currency`), e.g. `100000`; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed."
          },
          "bank_accounts": {
            "items": {
              "$ref": "#/components/schemas/PartyBankAccount"
            },
            "type": "array",
            "title": "Bank Accounts",
            "description": "Further accounts payments may go to."
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/PartyContact"
            },
            "type": "array",
            "title": "Contacts",
            "description": "People at the party (`GET /v1/contacts?party_id=`)."
          },
          "parent_party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Party Id",
            "description": "Id of the company it belongs to (a party of the same kind)."
          },
          "custom": {
            "additionalProperties": true,
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Customers: the sales person who looks after it (`GET /v1/people`); a vendor has none. Who sees only their own or their team's records gives it to one of those people."
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Correspondence language (`de`, `fr`, `it`, `en`, `sv`, `rm`)."
          },
          "default_account_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Account Id",
            "description": "Id of the revenue or expense account used on lines without an account."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "When the party was created (UTC)."
          },
          "balances": {
            "items": {
              "$ref": "#/components/schemas/Balance"
            },
            "type": "array",
            "title": "Balances",
            "description": "Open posted documents per currency: open and overdue amount and number of documents; credit notes count negative."
          },
          "pending_actions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Pending Actions",
            "description": "Requests waiting for a second person: activate_party, change_bank_details."
          },
          "created_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created By",
            "description": "From the audit trail."
          },
          "activated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Activated By",
            "description": "Who activated it last, if it started as a draft."
          },
          "activated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Activated At",
            "description": "When the party was last activated (UTC)."
          },
          "pending": {
            "items": {
              "$ref": "#/components/schemas/PendingRequest"
            },
            "type": "array",
            "title": "Pending",
            "description": "The requests waiting for a second person, with who asked and why."
          },
          "payment_blockers": {
            "items": {
              "$ref": "#/components/schemas/BlockerOut"
            },
            "type": "array",
            "title": "Payment Blockers",
            "description": "Why no payment to the party can be released now."
          },
          "vat_check": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PartyVatCheck"
              },
              {
                "type": "null"
              }
            ],
            "description": "The public register's last answer for the current VAT number, with its consultation reference as proof; null until it is checked from the card."
          },
          "credit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CreditPosition"
              },
              {
                "type": "null"
              }
            ],
            "description": "Customers with a credit limit: what the customer owes and has on order against its limit today, and the credit still available; null without a limit."
          },
          "parent": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PartyRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The company it belongs to."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "The owner (`owner_user_id`), by name."
          },
          "merged_into": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PartyRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The customer this duplicate was merged into (it is inactive)."
          },
          "subsidiaries": {
            "items": {
              "$ref": "#/components/schemas/PartyRef"
            },
            "type": "array",
            "title": "Subsidiaries",
            "description": "The parties that name it as their parent company."
          },
          "possible_duplicates": {
            "items": {
              "$ref": "#/components/schemas/PossibleDuplicate"
            },
            "type": "array",
            "title": "Possible Duplicates",
            "description": "Other customers or vendors of the same company with the same VAT number, an IBAN in common or the same name."
          },
          "open_support_cases": {
            "type": "integer",
            "title": "Open Support Cases",
            "description": "Support cases of this customer that are open or waiting on the customer.",
            "default": 0
          },
          "breached_support_cases": {
            "type": "integer",
            "title": "Breached Support Cases",
            "description": "Support cases of this customer where a service level is breached.",
            "default": 0
          },
          "active_subscriptions": {
            "type": "integer",
            "title": "Active Subscriptions",
            "description": "Active recurring subscriptions of this customer.",
            "default": 0
          },
          "open_opportunities": {
            "type": "integer",
            "title": "Open Opportunities",
            "description": "Open sales pipeline deals (opportunities) for this customer.",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "code",
          "name",
          "country",
          "subdivision",
          "vat_number",
          "business",
          "currency",
          "payment_terms_days",
          "email",
          "iban"
        ],
        "title": "PartyCard",
        "description": "One customer or vendor with everything its card shows."
      },
      "PartyContact": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the contact (`GET /v1/contacts/{contact_id}`)."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "First and last name."
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Role or department, e.g. `Buchhaltung`."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address."
          },
          "phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Phone",
            "description": "Phone number."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "title": "PartyContact",
        "description": "A person at a customer or vendor, as its card lists them."
      },
      "PartyCreated": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the customer or vendor."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`customer` or `vendor`."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The party's short code, e.g. `C-DE`; unique per kind in an entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 subdivision used for tax, if any."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "VAT or UID number."
          },
          "business": {
            "type": "boolean",
            "title": "Business",
            "description": "`true` for a business (B2B), `false` for a private person (B2C)."
          },
          "split_payment": {
            "type": "boolean",
            "title": "Split Payment",
            "description": "Italy: `true` for a customer under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter, e.g. a public body): an Italian company's invoices to it show the VAT, which the customer pays to the State, and the customer owes the net amount.",
            "default": false
          },
          "withholding_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Code",
            "description": "Vendors: the withholding tax code its bills keep back (`IT-RA-20`, `custom`); null for none."
          },
          "withholding_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Rate",
            "description": "Vendors: the withholding rate in percent of a bill's net amount before VAT."
          },
          "vat_unverified": {
            "type": "boolean",
            "title": "Vat Unverified",
            "description": "`true` for a vendor created from a received document whose `vat_number` (recorded as printed) is not a valid Swiss UID or German USt-IdNr; a later change of `vat_number` that passes the check clears it.",
            "default": false
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the party's documents and payments."
          },
          "payment_terms_days": {
            "type": "integer",
            "title": "Payment Terms Days",
            "description": "Days from the document date to the due date."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Contact email address."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "IBAN payments to the party go to, without spaces."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the postal address."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the postal address."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`active`; `draft` until a second person activates it (a draft is neither booked nor paid); `blocked` (no new documents or orders, nothing paid to it; what it pays still settles its open items) or `inactive` (no longer used, no open items).",
            "default": "active"
          },
          "group_entity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Group Entity Id",
            "description": "Id of the entity this customer or vendor is, when it is another entity of the organization (created by an approved intercompany relationship); null for an ordinary customer or vendor. Its documents post to the group accounts (`ic_ar_control`, `ic_ap_control`) and are mirrored in that entity."
          },
          "leitweg_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Leitweg Id",
            "description": "Leitweg-ID of a German public buyer (XRechnung buyer reference)."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "E-invoicing address (EN 16931 BT-34 / BT-49)."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "EAS code of the electronic address, e.g. `EM`."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount (Skonto) percent if paid within the days."
          },
          "cash_discount_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Days",
            "description": "Days within which the cash discount applies."
          },
          "credit_limit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Limit",
            "description": "Customers: the most the customer may owe, in its currency (`currency`), e.g. `100000`; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed."
          },
          "bank_accounts": {
            "items": {
              "$ref": "#/components/schemas/PartyBankAccount"
            },
            "type": "array",
            "title": "Bank Accounts",
            "description": "Further accounts payments may go to."
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/PartyContact"
            },
            "type": "array",
            "title": "Contacts",
            "description": "People at the party (`GET /v1/contacts?party_id=`)."
          },
          "parent_party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Party Id",
            "description": "Id of the company it belongs to (a party of the same kind)."
          },
          "custom": {
            "additionalProperties": true,
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Customers: the sales person who looks after it (`GET /v1/people`); a vendor has none. Who sees only their own or their team's records gives it to one of those people."
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Correspondence language (`de`, `fr`, `it`, `en`, `sv`, `rm`)."
          },
          "default_account_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Account Id",
            "description": "Id of the revenue or expense account used on lines without an account."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "When the party was created (UTC)."
          },
          "possible_duplicates": {
            "items": {
              "$ref": "#/components/schemas/PossibleDuplicate"
            },
            "type": "array",
            "title": "Possible Duplicates",
            "description": "Customers or vendors of the same company with the same VAT number, an IBAN in common or the same name. The party is created anyway (a vendor as a draft); check them before it is activated."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "code",
          "name",
          "country",
          "subdivision",
          "vat_number",
          "business",
          "currency",
          "payment_terms_days",
          "email",
          "iban"
        ],
        "title": "PartyCreated",
        "description": "A new customer or vendor, with the existing ones it may duplicate."
      },
      "PartyInput": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "customer",
              "vendor"
            ],
            "title": "Kind",
            "description": "`customer` or `vendor`; a code is unique per kind in an entity."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Leave it out and the party gets the company's next number: `C-00001` for a customer, `V-00001` for a vendor, counted per company without gaps. Give one (up to 40 characters, e.g. the number of the system before) only to keep it; it is how documents and URLs name the party, and never changes."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name of the customer or vendor."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code, e.g. `DE`; drives the place of supply of the tax determination. Omitted: the country its VAT number names by its prefix, else the company's."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 subdivision where it matters for tax, e.g. `DE-BY`, or a US customer's state (`US-CA`), which decides its sales tax. A Spanish postal code gives it when left empty: 35 and 38 the Canary Islands (`ES-CN`), 51 Ceuta (`ES-CE`), 52 Melilla (`ES-ML`); one of another country, or that the postal code contradicts, is refused (422 `party_subdivision_mismatch`)."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "VAT or UID number, e.g. `DE811569869` or `CHE-116.281.710 MWST`; for a party of an EU country, the UK, Norway, Switzerland or Liechtenstein its format is checked, and its check digit for CH, DE, FR, IT, ES and BE (422 `vat_number_invalid`)."
          },
          "business": {
            "type": "boolean",
            "title": "Business",
            "description": "`true` for a business (B2B), `false` for a private person (B2C); affects how VAT is determined on sales: a sale to another VAT area goes under the reverse charge only to a business, and a customer with a VAT number counts as one. Between two EU countries only the VAT number makes the customer a business: without it the sale is taxed as one to a private person.",
            "default": true
          },
          "split_payment": {
            "type": "boolean",
            "title": "Split Payment",
            "description": "Customers of an Italian company: `true` for one under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter: public bodies and the companies the law lists). Its invoices show the VAT but it owes only the net amount and pays the VAT to the State; the VAT returns leave that VAT out. Default false.",
            "default": false
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency of the party's documents and payments, e.g. `EUR`: functional or with exchange rates (422 `party_currency_without_rates`). Omitted: its country's currency when the company has exchange rates for it, else the company's."
          },
          "withholding_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 20
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Code",
            "description": "Vendors: the withholding tax code kept back from its bills and paid to the tax authority by the company (`GET /v1/entities/{entity}/withholding-tax/codes` lists the codes of the company's country, e.g. `IT-RA-20`), or `custom` with `withholding_rate`; null for none. Changing it once a bill of the vendor is posted waits for a second person."
          },
          "withholding_rate": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Rate",
            "description": "With `withholding_code` `custom`: the rate in percent of a bill's net amount before VAT, e.g. `18.5`; a code of the table takes its own rate."
          },
          "payment_terms_days": {
            "type": "integer",
            "maximum": 365.0,
            "minimum": 0.0,
            "title": "Payment Terms Days",
            "description": "Days from the document date to the due date, 0 to 365; default 30.",
            "default": 30
          },
          "default_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Account",
            "description": "Revenue/expense account code."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Contact email address."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "IBAN payments to the party go to, stored without spaces; one of your own companies' accounts is refused (422 `party_own_bank_account`)."
          },
          "bank_accounts": {
            "items": {
              "$ref": "#/components/schemas/PartyBankAccount"
            },
            "type": "array",
            "title": "Bank Accounts",
            "description": "Further accounts payments may go to (a QR-IBAN)."
          },
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "rm",
                  "sv"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Correspondence language. Omitted: its country's, where the country has one of ours (DE and AT `de`, FR `fr`, IT `it`, SE `sv`, GB and US `en`); none for a country of several (CH, BE, CA): set it there."
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/NewContact"
            },
            "type": "array",
            "title": "Contacts",
            "description": "People at the party; later ones are added with `POST /v1/contacts`."
          },
          "parent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent",
            "description": "Code (or id) of the company it belongs to, of the same kind."
          },
          "custom": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "integer"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Customers: the sales person who looks after it (`GET /v1/people`); a vendor has none. Who sees only their own or their team's records gives it to one of those people. Omitted: you."
          },
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the postal address (up to 70 characters); used on QR-bills and XRechnung."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the postal address (up to 16 characters)."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address (up to 16 characters)."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address (up to 35 characters)."
          },
          "leitweg_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Leitweg Id",
            "description": "Customers: Leitweg-ID of a German public buyer (XRechnung buyer reference)."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "E-invoicing address (BT-34/BT-49), e.g. an email or Peppol id."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "EAS code of the electronic address, e.g. EM (email), 0204, 9930."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "draft"
            ],
            "title": "Status",
            "description": "draft until a second person activates it. A vendor (or a party with bank details) created by an agent, and a vendor created from an e-invoice, start as draft; otherwise 'active' needs the approval policy to allow activate_party.",
            "default": "active"
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount (Skonto) percent if paid within cash_discount_days, e.g. 2."
          },
          "cash_discount_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Days",
            "description": "Days within which the cash discount applies, 0 to 365."
          },
          "credit_limit": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,18}|(?=[\\d.]{1,21}0*$)\\d{0,18}\\.\\d{0,2}0*$)"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Limit",
            "description": "Customers: the most the customer may owe, in its currency (`currency`), e.g. `100000`; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed."
          },
          "source_sha256": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[0-9a-f]{64}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Sha256",
            "description": "SHA-256 of the bill this vendor was read from (the bill wizard sends the `sha256` of `POST /v1/agents/bill-capture/read`). The audit entry and the activation request then say that its bank details come from that invoice, and what the public VAT register said about its number: the approver sees what nobody has confirmed."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "name"
        ],
        "title": "PartyInput",
        "examples": [
          {
            "building_number": "1268",
            "contacts": [
              {
                "first_name": "Anna",
                "last_name": "Muster",
                "role": "Buchhaltung"
              }
            ],
            "country": "CH",
            "currency": "CHF",
            "iban": "CH44 3199 9123 0008 8901 2",
            "kind": "vendor",
            "language": "de",
            "name": "Neu Handel AG",
            "payment_terms_days": 20,
            "postal_code": "2501",
            "street": "Rue du Lac",
            "town": "Biel"
          }
        ]
      },
      "PartyRef": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the party."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Its code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name"
        ],
        "title": "PartyRef",
        "description": "Another customer or vendor named by this one (its parent company or a subsidiary)."
      },
      "PartyRow": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the customer or vendor."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`customer` or `vendor`."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The party's short code, e.g. `C-DE`; unique per kind in an entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 subdivision used for tax, if any."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "VAT or UID number."
          },
          "business": {
            "type": "boolean",
            "title": "Business",
            "description": "`true` for a business (B2B), `false` for a private person (B2C)."
          },
          "split_payment": {
            "type": "boolean",
            "title": "Split Payment",
            "description": "Italy: `true` for a customer under split payment (scissione dei pagamenti, DPR 633/1972 art. 17-ter, e.g. a public body): an Italian company's invoices to it show the VAT, which the customer pays to the State, and the customer owes the net amount.",
            "default": false
          },
          "withholding_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Code",
            "description": "Vendors: the withholding tax code its bills keep back (`IT-RA-20`, `custom`); null for none."
          },
          "withholding_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Rate",
            "description": "Vendors: the withholding rate in percent of a bill's net amount before VAT."
          },
          "vat_unverified": {
            "type": "boolean",
            "title": "Vat Unverified",
            "description": "`true` for a vendor created from a received document whose `vat_number` (recorded as printed) is not a valid Swiss UID or German USt-IdNr; a later change of `vat_number` that passes the check clears it.",
            "default": false
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the party's documents and payments."
          },
          "payment_terms_days": {
            "type": "integer",
            "title": "Payment Terms Days",
            "description": "Days from the document date to the due date."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Contact email address."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "IBAN payments to the party go to, without spaces."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the postal address."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the postal address."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`active`; `draft` until a second person activates it (a draft is neither booked nor paid); `blocked` (no new documents or orders, nothing paid to it; what it pays still settles its open items) or `inactive` (no longer used, no open items).",
            "default": "active"
          },
          "group_entity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Group Entity Id",
            "description": "Id of the entity this customer or vendor is, when it is another entity of the organization (created by an approved intercompany relationship); null for an ordinary customer or vendor. Its documents post to the group accounts (`ic_ar_control`, `ic_ap_control`) and are mirrored in that entity."
          },
          "leitweg_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Leitweg Id",
            "description": "Leitweg-ID of a German public buyer (XRechnung buyer reference)."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "E-invoicing address (EN 16931 BT-34 / BT-49)."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "EAS code of the electronic address, e.g. `EM`."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount (Skonto) percent if paid within the days."
          },
          "cash_discount_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Days",
            "description": "Days within which the cash discount applies."
          },
          "credit_limit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Limit",
            "description": "Customers: the most the customer may owe, in its currency (`currency`), e.g. `100000`; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed."
          },
          "bank_accounts": {
            "items": {
              "$ref": "#/components/schemas/PartyBankAccount"
            },
            "type": "array",
            "title": "Bank Accounts",
            "description": "Further accounts payments may go to."
          },
          "contacts": {
            "items": {
              "$ref": "#/components/schemas/PartyContact"
            },
            "type": "array",
            "title": "Contacts",
            "description": "People at the party (`GET /v1/contacts?party_id=`)."
          },
          "parent_party_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent Party Id",
            "description": "Id of the company it belongs to (a party of the same kind)."
          },
          "custom": {
            "additionalProperties": true,
            "type": "object",
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Customers: the sales person who looks after it (`GET /v1/people`); a vendor has none. Who sees only their own or their team's records gives it to one of those people."
          },
          "language": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Correspondence language (`de`, `fr`, `it`, `en`, `sv`, `rm`)."
          },
          "default_account_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Account Id",
            "description": "Id of the revenue or expense account used on lines without an account."
          },
          "created_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created At",
            "description": "When the party was created (UTC)."
          },
          "balances": {
            "items": {
              "$ref": "#/components/schemas/Balance"
            },
            "type": "array",
            "title": "Balances",
            "description": "Open posted documents per currency: open and overdue amount and number of documents; credit notes count negative."
          },
          "pending_actions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Pending Actions",
            "description": "Requests waiting for a second person: activate_party, change_bank_details."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "code",
          "name",
          "country",
          "subdivision",
          "vat_number",
          "business",
          "currency",
          "payment_terms_days",
          "email",
          "iban"
        ],
        "title": "PartyRow",
        "description": "A customer or vendor in a list, with its open balance and pending requests."
      },
      "PartyStatusInput": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "active",
              "blocked",
              "inactive"
            ],
            "title": "Status",
            "description": "`blocked`: no new documents or orders, nothing paid to it. `inactive`: no longer used (only without open items). `active`: in use again."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why; the approver sees it and it is audited."
          }
        },
        "type": "object",
        "required": [
          "status",
          "reason"
        ],
        "title": "PartyStatusInput",
        "description": "A request to block a customer or vendor, set it inactive, or make it active again.",
        "examples": [
          {
            "reason": "Disputed deliveries, legal review",
            "status": "blocked"
          }
        ]
      },
      "PartyUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New legal name; once the party is past draft, or a document of it is posted or pending approval, this waits for a second person."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "New ISO 3166-1 alpha-2 country; waits for a second person like `name`."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^([A-Z]{2}-[A-Z0-9]{1,3})?$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 subdivision where it matters for tax, e.g. `DE-BY`, or a US customer's state (`US-CA`); empty clears it. A Spanish postal code gives it as on create (422 `party_subdivision_mismatch` on a contradiction); a change waits for a second person like `name`."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "New VAT or UID number (format checked as on create, 422); waits for a second person like `name`."
          },
          "business": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Business",
            "description": "`true` for a business (B2B), `false` for a private person (B2C); affects how VAT is determined on sales: a sale to another VAT area goes under the reverse charge only to a business, and a customer with a VAT number counts as one. Between two EU countries only the VAT number makes the customer a business: without it the sale is taxed as one to a private person."
          },
          "split_payment": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Split Payment",
            "description": "Customers of an Italian company: `true` for one under split payment (DPR 633/1972 art. 17-ter); applies to invoices drafted from then on."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "New ISO 4217 currency: the functional currency or one with exchange rates (422 `party_currency_without_rates`); waits for a second person like `name`."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Contact email address."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "New IBAN, stored without spaces. It is not applied at once: a second person must approve it and payments to the party are blocked meanwhile. `\"\"` clears it."
          },
          "bank_accounts": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/PartyBankAccount"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Accounts",
            "description": "New list of further bank accounts; replaces the list. Waits for a second person's approval like `iban`."
          },
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "rm",
                  "sv"
                ]
              },
              {
                "type": "string",
                "const": ""
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Correspondence language (`de`, `fr`, `it`, `en`, `sv`, `rm`); `\"\"` clears."
          },
          "parent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Parent",
            "description": "Code (or id) of the company it belongs to; `\"\"` clears it."
          },
          "custom": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    },
                    {
                      "type": "integer"
                    },
                    {
                      "type": "boolean"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Custom",
            "description": "Values of the organization's own fields (`GET /v1/custom-fields`) by key, e.g. `{\"industry\": \"Retail\"}`: text, a number, a date (`2026-10-23`), true or false, or one of a choice field's choices. On a change only the keys sent change; null removes a value."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "New owner. Customers: the sales person who looks after it (`GET /v1/people`); a vendor has none. Who sees only their own or their team's records gives it to one of those people."
          },
          "withholding_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 20
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Code",
            "description": "Vendors: the withholding tax code kept back from its bills and paid to the tax authority by the company (`GET /v1/entities/{entity}/withholding-tax/codes` lists the codes of the company's country, e.g. `IT-RA-20`), or `custom` with `withholding_rate`; `\"\"` removes it. Waits for a second person like `name`."
          },
          "withholding_rate": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Withholding Rate",
            "description": "With `withholding_code` `custom`: the rate in percent of a bill's net amount before VAT."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Days from the document date to the due date, 0 to 365; waits for a second person like `name`."
          },
          "default_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default Account",
            "description": "Code of the revenue (customer) or expense (vendor) account used on document lines that name no account, e.g. `6570`."
          },
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the postal address (up to 70 characters); used on QR-bills and XRechnung."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the postal address (up to 16 characters)."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address (up to 16 characters)."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address (up to 35 characters)."
          },
          "leitweg_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Leitweg Id",
            "description": "Customers: the Leitweg-ID of a German public buyer (validated, including its check digits); becomes the XRechnung buyer reference."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "E-invoicing address (EN 16931 BT-34 / BT-49), e.g. an email address or a Peppol id."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "Scheme of the electronic address (EAS code), e.g. `EM` (email), `0204` or `9930`; needs an `electronic_address`."
          },
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "active",
                  "draft"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "'active' activates a draft party (as POST …/activate); 'draft' blocks its documents and payments again."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "0 removes the terms; waits like `name`."
          },
          "cash_discount_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Days",
            "description": "Days within which the cash discount applies, 0 to 365; waits for a second person like `name`."
          },
          "credit_limit": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,18}|(?=[\\d.]{1,21}0*$)\\d{0,18}\\.\\d{0,2}0*$)"
              },
              {
                "type": "string",
                "const": ""
              },
              {
                "type": "null"
              }
            ],
            "title": "Credit Limit",
            "description": "Customers: the most the customer may owe, in its currency (`currency`), e.g. `100000`; null for no limit. Its open invoices, its invoices waiting for approval and what is left to invoice on its open sales orders count; above it an invoice waits for a second person and a sales order is not confirmed. `\"\"` removes the limit. Waits for a second person like `name`."
          }
        },
        "type": "object",
        "title": "PartyUpdate",
        "description": "Fields that can be changed (null leaves a field as is, \"\" clears it).\n\nBank details (``iban``, ``bank_accounts``) are not changed at once: the change waits for a\nsecond person's approval and payments are blocked meanwhile, as are key details of a party past\ndraft or with posted documents. ``status: active`` does what the activate operation does.",
        "examples": [
          {
            "language": "de",
            "parent": "C-GROUP",
            "payment_terms_days": 20
          }
        ]
      },
      "PartyVatCheck": {
        "properties": {
          "registry": {
            "type": "string",
            "enum": [
              "ch_uid",
              "uk_hmrc",
              "vies"
            ],
            "title": "Registry",
            "description": "The register that answered."
          },
          "status": {
            "type": "string",
            "enum": [
              "invalid",
              "valid"
            ],
            "title": "Status",
            "description": "`valid`: registered for VAT; `invalid`: the register does not know it."
          },
          "vat_number": {
            "type": "string",
            "title": "Vat Number",
            "description": "The number as it was asked, compacted."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The registered name, if given."
          },
          "name_matches": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name Matches",
            "description": "Whether the registered name matches the party's name."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The register's consultation reference, kept as proof (HMRC's consultation number when your entity has a UK VAT number)."
          },
          "checked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Checked At",
            "description": "When the register answered (UTC)."
          },
          "checked_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checked By",
            "description": "Who asked."
          }
        },
        "type": "object",
        "required": [
          "registry",
          "status",
          "vat_number",
          "checked_at"
        ],
        "title": "PartyVatCheck",
        "description": "The register's last definite answer for a customer's or vendor's VAT number."
      },
      "PassInput": {
        "properties": {
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of this pass's notes and questions.",
            "default": "en"
          }
        },
        "additionalProperties": false,
        "type": "object",
        "title": "PassInput",
        "examples": [
          {
            "language": "en"
          }
        ]
      },
      "PassOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The pass's id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "outcome": {
            "type": "string",
            "title": "Outcome",
            "description": "The outcome, e.g. `bank_matched`."
          },
          "trigger": {
            "type": "string",
            "enum": [
              "daily",
              "event",
              "person"
            ],
            "title": "Trigger",
            "description": "What started it: `event` (something happened, see `reason`), `daily` (the daily pass), `person` (Run now)."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why, e.g. `bank statement imported`."
          },
          "acting_for": {
            "type": "string",
            "title": "Acting For",
            "description": "The person whose work it counts as."
          },
          "run_on": {
            "type": "string",
            "format": "date",
            "title": "Run On",
            "description": "The company's day it ran on."
          },
          "status": {
            "type": "string",
            "enum": [
              "done",
              "failed",
              "running"
            ],
            "title": "Status",
            "description": "`running`, `done` or `failed`."
          },
          "open_before": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Open Before",
            "description": "Items not yet true when it started."
          },
          "open_after": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Open After",
            "description": "Items not yet true when it ended."
          },
          "by_rules": {
            "type": "integer",
            "title": "By Rules",
            "description": "Items the rules (code, no AI) settled."
          },
          "by_ai": {
            "type": "integer",
            "title": "By Ai",
            "description": "Items the AI settled, as the outcome's check found after."
          },
          "ai_items": {
            "type": "integer",
            "title": "Ai Items",
            "description": "Items sent to the AI (what counts against the budget)."
          },
          "log": {
            "items": {
              "$ref": "#/components/schemas/LogLine"
            },
            "type": "array",
            "title": "Log",
            "description": "What it did, step by step."
          },
          "handoffs": {
            "items": {
              "$ref": "#/components/schemas/Handoff"
            },
            "type": "array",
            "title": "Handoffs",
            "description": "What it left a person, each with its place."
          },
          "questions": {
            "items": {
              "$ref": "#/components/schemas/QuestionOut"
            },
            "type": "array",
            "title": "Questions",
            "description": "What the AI asked a person in this pass."
          },
          "model": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Model",
            "description": "The model that judged, if any did."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why it failed."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "title": "Started At",
            "description": "When it started."
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At",
            "description": "When it ended."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "outcome",
          "trigger",
          "reason",
          "acting_for",
          "run_on",
          "status",
          "open_before",
          "open_after",
          "by_rules",
          "by_ai",
          "ai_items",
          "log",
          "handoffs",
          "questions",
          "model",
          "error",
          "started_at",
          "finished_at"
        ],
        "title": "PassOut"
      },
      "PassSummary": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The pass's id."
          },
          "outcome": {
            "type": "string",
            "title": "Outcome",
            "description": "The outcome."
          },
          "trigger": {
            "type": "string",
            "enum": [
              "daily",
              "event",
              "person"
            ],
            "title": "Trigger",
            "description": "What started it."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why."
          },
          "acting_for": {
            "type": "string",
            "title": "Acting For",
            "description": "The person whose work it counts as."
          },
          "status": {
            "type": "string",
            "enum": [
              "done",
              "failed",
              "running"
            ],
            "title": "Status",
            "description": "`running`, `done` or `failed`."
          },
          "open_before": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Open Before",
            "description": "Items open when it started."
          },
          "open_after": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Open After",
            "description": "Items open when it ended."
          },
          "by_rules": {
            "type": "integer",
            "title": "By Rules",
            "description": "Settled by the rules."
          },
          "by_ai": {
            "type": "integer",
            "title": "By Ai",
            "description": "Settled by the AI."
          },
          "ai_items": {
            "type": "integer",
            "title": "Ai Items",
            "description": "Sent to the AI."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why it failed."
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "title": "Started At",
            "description": "When it started."
          },
          "finished_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finished At",
            "description": "When it ended."
          }
        },
        "type": "object",
        "required": [
          "id",
          "outcome",
          "trigger",
          "reason",
          "acting_for",
          "status",
          "open_before",
          "open_after",
          "by_rules",
          "by_ai",
          "ai_items",
          "error",
          "started_at",
          "finished_at"
        ],
        "title": "PassSummary"
      },
      "PasskeyAnswer": {
        "properties": {
          "credential": {
            "additionalProperties": true,
            "type": "object",
            "title": "Credential",
            "description": "The browser's answer, as JSON (`PublicKeyCredential.toJSON()`)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "For a new passkey: a name the person recognises it by (\"MacBook\", \"Phone\"). Ignored for a touch."
          }
        },
        "type": "object",
        "required": [
          "credential"
        ],
        "title": "PasskeyAnswer",
        "examples": [
          {
            "credential": {
              "id": "q2Vx...",
              "rawId": "q2Vx...",
              "response": {
                "authenticatorData": "SZYN...",
                "clientDataJSON": "eyJ0..."
              },
              "type": "public-key"
            }
          }
        ]
      },
      "PasskeyOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the passkey."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The name the person gave it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was created (ISO 8601, UTC)."
          },
          "last_used_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Used At",
            "description": "When it was last touched (ISO 8601, UTC)."
          },
          "backed_up": {
            "type": "boolean",
            "title": "Backed Up",
            "description": "`true` when a password manager keeps a copy (iCloud Keychain, Google Password Manager), so a new device gets it; `false` for a key bound to one device."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "created_at",
          "last_used_at",
          "backed_up"
        ],
        "title": "PasskeyOut"
      },
      "PasskeyReset": {
        "properties": {
          "removed": {
            "type": "integer",
            "title": "Removed",
            "description": "How many passkeys were removed."
          }
        },
        "type": "object",
        "required": [
          "removed"
        ],
        "title": "PasskeyReset"
      },
      "PasskeyStep": {
        "properties": {
          "setup": {
            "type": "boolean",
            "title": "Setup",
            "description": "`true`: create a passkey (`navigator.credentials.create`); `false`: touch one (`navigator.credentials.get`)."
          },
          "options": {
            "additionalProperties": true,
            "type": "object",
            "title": "Options",
            "description": "The WebAuthn options as JSON (`PublicKeyCredentialCreationOptionsJSON` or `PublicKeyCredentialRequestOptionsJSON`), for `PublicKeyCredential.parseCreationOptionsFromJSON` or `parseRequestOptionsFromJSON`. They hold a one-time challenge valid for five minutes."
          }
        },
        "type": "object",
        "required": [
          "setup",
          "options"
        ],
        "title": "PasskeyStep"
      },
      "PasswordEmailSent": {
        "properties": {
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The address Google sent the e-mail to."
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "PasswordEmailSent"
      },
      "PasswordLogin": {
        "properties": {
          "credential": {
            "type": "string",
            "title": "Credential",
            "description": "The ID token Google Identity Platform returned for an e-mail and password sign-in (`idToken` of `accounts:signInWithPassword`)."
          },
          "org_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Org Id",
            "description": "Chosen organization."
          }
        },
        "type": "object",
        "required": [
          "credential"
        ],
        "title": "PasswordLogin",
        "examples": [
          {
            "credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ij..."
          }
        ]
      },
      "PasswordSignIn": {
        "properties": {
          "api_key": {
            "type": "string",
            "title": "Api Key",
            "description": "The browser API key of Google Identity Platform (public, like an OAuth client id)."
          },
          "project": {
            "type": "string",
            "title": "Project",
            "description": "The Google Cloud project the password accounts live in."
          }
        },
        "type": "object",
        "required": [
          "api_key",
          "project"
        ],
        "title": "PasswordSignIn"
      },
      "PaymentExportOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the payment export."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "message_id": {
            "type": "string",
            "title": "Message Id",
            "description": "Message id of the pain.001 file, e.g. `ERP-20260930-1A2B3C4D5E6F`."
          },
          "format": {
            "type": "string",
            "title": "Format",
            "description": "File format: `pain.001.001.09.ch.03` (SPS credit transfers) or `pain.008.001.08` (SEPA direct debits)."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "Name of the file."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the file, hex; also in the `X-Content-SHA256` header."
          },
          "payment_count": {
            "type": "integer",
            "title": "Payment Count",
            "description": "Number of payments in the file."
          },
          "control_sum": {
            "type": "string",
            "title": "Control Sum",
            "description": "Sum of the payment amounts."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "The actor that released the file."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was released (UTC)."
          },
          "payments": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Payments",
            "description": "Numbers of the payments in the file."
          },
          "execution_dates": {
            "items": {
              "$ref": "#/components/schemas/ExecutionDate"
            },
            "type": "array",
            "title": "Execution Dates",
            "description": "Requested and actual execution date of each payment."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "message_id",
          "format",
          "filename",
          "sha256",
          "payment_count",
          "control_sum",
          "created_by",
          "created_at",
          "payments"
        ],
        "title": "PaymentExportOut"
      },
      "PaymentInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity paying or receiving, e.g. `CH01`."
          },
          "direction": {
            "type": "string",
            "enum": [
              "incoming",
              "outgoing"
            ],
            "title": "Direction",
            "description": "`incoming`: a receipt from a customer; `outgoing`: a payment to a vendor."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Customer or vendor code (or id), e.g. `C-DE` or `V-BM`."
          },
          "payment_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Date",
            "description": "Value date of the payment (ISO 8601); default today where the company is. The exchange rate of this day gives the realised FX difference. The fiscal period must be open. A receipt (`incoming`) is not dated after today (`receipt_in_future`), nor is a payment made (`payment_in_future`: a payment file asks the bank for a later execution date); neither is dated before a document it settles (`payment_before_document`)."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Total amount paid, a decimal string such as `1500.00`; it must equal the sum of the allocation amounts and `on_account` (cash discounts are on top of it)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code of the payment; default: the party's currency. A document in another currency is settled too: its allocation names what it settles in the document's currency (`document_amount`)."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "GL bank account code; default: the main bank account (role 'bank') when it holds the payment's currency, else the first active bank account in that currency, else the main one. A receipt collected by a payment provider (Shopify Payments) names the provider's balance (role 'provider_balance'), never a default."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Free text reference, e.g. the bill number or a bank reference."
          },
          "allocations": {
            "items": {
              "$ref": "#/components/schemas/AllocationInput-Input"
            },
            "type": "array",
            "title": "Allocations",
            "description": "The documents the payment settles: each allocation names a posted document of the party and the amount applied. May be empty when the whole amount is `on_account`."
          },
          "on_account": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "On Account",
            "description": "The part of the amount allocated to no document, e.g. an overpayment or an advance: it stays on the party's account (an open item of the party in the aging and the statement) until it is applied to an invoice or bill with `POST /v1/applications`. Default 0: the allocations take the whole amount.",
            "default": "0"
          },
          "bank_line_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Line Id",
            "description": "Id of the bank statement line the payment records, when it is entered from a bank statement; such a payment counts as already executed and is not put into a payment file."
          },
          "party_kind": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "customer",
                  "vendor"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Party Kind",
            "description": "Defaults to customer for incoming, vendor for outgoing; set it for refunds."
          },
          "executed": {
            "type": "boolean",
            "title": "Executed",
            "description": "Outgoing payments only: `true` when the bank already executed the payment (paid in e-banking, by card or in cash): it is booked on the bank account at once and goes into no payment file. Default `false`: the payment awaits execution by the bank (a payment file, or a transfer still to be made) and is booked on the payments-in-transit account (role `payments_in_transit`) until the bank statement line that shows it is matched, which moves it to the bank account (ADR-0060). A payment recorded from a bank line (`bank_line_id`) and a receipt always go to the bank account.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "entity",
          "direction",
          "party",
          "amount"
        ],
        "title": "PaymentInput",
        "examples": [
          {
            "allocations": [
              {
                "amount": "1200.00",
                "document": "BILL-2026-000001"
              }
            ],
            "amount": "1200.00",
            "bank_account": "1020",
            "direction": "outgoing",
            "entity": "CH01",
            "party": "V-BM",
            "payment_date": "2026-09-30",
            "reference": "BM-4411"
          }
        ]
      },
      "PaymentMeans": {
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "BT-81 UNTDID 4461"
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Text",
            "description": "BT-82"
          },
          "account_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Id",
            "description": "BT-84 IBAN or account number"
          },
          "account_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Name",
            "description": "BT-85"
          },
          "bic": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bic",
            "description": "BT-86"
          },
          "card_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Card Number",
            "description": "BT-87 (masked)"
          },
          "card_holder": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Card Holder",
            "description": "BT-88"
          },
          "mandate_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Mandate Id",
            "description": "BT-89"
          },
          "debited_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Debited Account",
            "description": "BT-91"
          }
        },
        "type": "object",
        "title": "PaymentMeans",
        "description": "BG-16 with credit transfer (BG-17), card (BG-18) or direct debit (BG-19)."
      },
      "PaymentOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the payment."
          },
          "direction": {
            "type": "string",
            "title": "Direction",
            "description": "`incoming` (receipt) or `outgoing` (payment)."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer or vendor."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Payment number such as `PAY-2026-000001` or `RCPT-2026-000001`, assigned when it is posted; null before."
          },
          "payment_date": {
            "type": "string",
            "format": "date",
            "title": "Payment Date",
            "description": "Value date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the payment."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount paid, in the payment currency."
          },
          "bank_account_id": {
            "type": "string",
            "format": "uuid",
            "title": "Bank Account Id",
            "description": "Id of the GL bank account."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Free text reference."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `posted`, `rejected` or `reversed` (its reversal is posted and the documents it settled are open again)."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "Id of the payment's journal entry."
          },
          "reversal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversal Entry Id",
            "description": "Id of the entry that reverses the payment's entry, once a reversal was asked for (`POST /v1/payments/{payment_id}/reverse`): posted when the payment is `reversed`, else waiting for approval (or rejected); null before."
          }
        },
        "type": "object",
        "required": [
          "id",
          "direction",
          "party_id",
          "number",
          "payment_date",
          "currency",
          "amount",
          "bank_account_id",
          "reference",
          "status",
          "journal_entry_id"
        ],
        "title": "PaymentOut"
      },
      "PaymentProposal": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "payment_date": {
            "type": "string",
            "format": "date",
            "title": "Payment Date",
            "description": "The day the proposal books the payments on."
          },
          "due_until": {
            "type": "string",
            "format": "date",
            "title": "Due Until",
            "description": "Bills due on or before this date are proposed."
          },
          "take_discounts": {
            "type": "boolean",
            "title": "Take Discounts",
            "description": "Whether cash discounts are deducted."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ProposalLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The proposed bills, ordered by vendor and due date."
          },
          "totals_by_currency": {
            "additionalProperties": {
              "$ref": "#/components/schemas/CurrencyTotal"
            },
            "type": "object",
            "title": "Totals By Currency",
            "description": "Bills, amount and discount per currency."
          },
          "skipped": {
            "items": {
              "$ref": "#/components/schemas/SkippedBill"
            },
            "type": "array",
            "title": "Skipped",
            "description": "Bills that would be due but are left out, with why (`code`): `bill_payment_blocked` (a purchase order variance waits for approval), `bill_settled_elsewhere` (another process settles it: a purchase on a company card, which the card issuer collects), `party_blocked`, `party_inactive` or `party_block_waiting`."
          },
          "bank_balances": {
            "items": {
              "$ref": "#/components/schemas/BankBalance"
            },
            "type": "array",
            "title": "Bank Balances",
            "description": "Per currency of the proposed bills, the bank account the run would pay from and its book balance on the payment date: when the bills chosen add up to more (in the account's currency), the run takes it below zero in the books and says so in its `warnings`; it is not refused."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "payment_date",
          "due_until",
          "take_discounts",
          "lines",
          "totals_by_currency"
        ],
        "title": "PaymentProposal"
      },
      "PaymentResult": {
        "properties": {
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "title": "Payment Id",
            "description": "Id of the new payment."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, or `pending_approval` when the approval policy needs a second person."
          },
          "fx_difference": {
            "type": "string",
            "title": "Fx Difference",
            "description": "Realised FX gain (positive) or loss (negative) booked, in the functional currency; 0 without a currency difference."
          },
          "discount": {
            "type": "string",
            "title": "Discount",
            "description": "Cash discount taken (all documents).",
            "default": "0.00"
          },
          "in_transit": {
            "type": "boolean",
            "title": "In Transit",
            "description": "The payment was booked on the payments-in-transit account, not on the bank account: it awaits execution by the bank (ADR-0060).",
            "default": false
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "How the submission went: `policy` (`allow` or `require_approval`), entry id and `approval_id`."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "What to know that did not stop it, in English: an outgoing payment that takes its bank account below zero in the books on the payment date (the money may be there and not booked yet)."
          },
          "warning_reasons": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Warning Reasons",
            "description": "The same by code (`bankBalance.warning.overdrawn`, with `account`, `entity`, `balance`, `after`, `currency` and `on`; `overdrawn_in_transit` adds `in_transit` when payments the bank has not executed yet count towards it), in the order of `warnings`."
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "status",
          "fx_difference",
          "submit"
        ],
        "title": "PaymentResult"
      },
      "PaymentReversalResult": {
        "properties": {
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "title": "Payment Id",
            "description": "Id of the payment."
          },
          "status": {
            "type": "string",
            "enum": [
              "posted",
              "reversed"
            ],
            "title": "Status",
            "description": "`reversed`: the reversal is posted, the documents the payment settled are open again; `posted`: the reversal waits for a second person (`reversal.approval_id`) and the payment stands until it is approved."
          },
          "reversal": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "The reversal entry's submission: `policy`, entry id, its number once posted and the `approval_id` while it waits."
          },
          "released_in": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Released In",
            "description": "The message id of the payment file the payment was released in, if it was: make sure the bank did not execute it (such a reversal always waits for a second person)."
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "status",
          "reversal"
        ],
        "title": "PaymentReversalResult"
      },
      "PaymentReverseRequest": {
        "properties": {
          "on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "On",
            "description": "Date of the reversal entry, ISO 8601: not before the payment date, in an open period. Default: today, or the payment date when it is later (a scheduled outgoing payment)."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the payment is reversed (required, at most 500 characters): on the reversal entry, in the approval request and in the audit trail."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "PaymentReverseRequest",
        "examples": [
          {
            "on": "2026-10-10",
            "reason": "Booked twice"
          }
        ]
      },
      "PaymentRow": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the payment."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Payment number such as `PAY-2026-000001`; null before it is posted."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Vendor or customer code."
          },
          "party_name": {
            "type": "string",
            "title": "Party Name",
            "description": "Vendor or customer name."
          },
          "party_kind": {
            "type": "string",
            "enum": [
              "customer",
              "vendor"
            ],
            "title": "Party Kind",
            "description": "`vendor`, or `customer` for a refund paid back to a customer (an outgoing payment) or a receipt from a customer."
          },
          "payment_date": {
            "type": "string",
            "format": "date",
            "title": "Payment Date",
            "description": "Value date."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount, in the payment currency."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the payment."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `posted`, `rejected` or `reversed`; only `posted` payments can be released or reversed."
          },
          "reversal_pending": {
            "type": "boolean",
            "title": "Reversal Pending",
            "description": "A reversal of the payment waits for a second person (`GET /v1/approvals`).",
            "default": false
          },
          "bank_account": {
            "type": "string",
            "title": "Bank Account",
            "description": "Code of the GL bank account it is paid from."
          },
          "booked_on": {
            "type": "string",
            "title": "Booked On",
            "description": "Code of the account the payment's entry booked the money on: the payments-in-transit account while an outgoing payment awaits execution by the bank, else the bank account (ADR-0060).",
            "default": ""
          },
          "bank_status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "executed",
                  "in_transit"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Status",
            "description": "Where a posted payment stands with the bank: `in_transit` (booked on the payments-in-transit account, no bank line shows its execution yet) or `executed` (a bank line is matched to it, which moved it to the bank account, or it was booked on the bank account at once: a receipt, or a payment recorded from a bank line or as already executed); null when it is not posted."
          },
          "creditor_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Creditor Iban",
            "description": "The IBAN the payment goes to."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The structured reference (QR or creditor) carried, if any."
          },
          "payment_type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "D",
                  "S"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Type",
            "description": "pain.001 payment type: `D` (domestic, to a CH/LI account) or `S` (SEPA); null when it cannot be classified yet."
          },
          "execution_status": {
            "type": "string",
            "enum": [
              "open",
              "sent"
            ],
            "title": "Execution Status",
            "description": "`open` (not in a payment file) or `sent` (released)."
          },
          "export": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ExportInfo"
              },
              {
                "type": "null"
              }
            ],
            "description": "The payment file it was released in, once sent."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "Id of the payment's journal entry; null before it is posted."
          },
          "problems": {
            "items": {
              "$ref": "#/components/schemas/BlockerOut"
            },
            "type": "array",
            "title": "Problems",
            "description": "Why the payment cannot be released, if anything."
          },
          "bank_line": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BankConfirmation"
              },
              {
                "type": "null"
              }
            ],
            "description": "The bank statement line that shows the bank executed the payment (matched to it, or the line it was recorded from); null until a statement shows it. A payment with one is not reversed: undoing the match (`POST /v1/bank-lines/{id}/unmatch`) is."
          },
          "bank_refusal": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BankRefusal"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the bank rejected or returned the payment (ADR-0062): why, and whether its reversal is posted or waits for a second person; null otherwise."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "party_code",
          "party_name",
          "party_kind",
          "payment_date",
          "amount",
          "currency",
          "status",
          "bank_account",
          "creditor_iban",
          "reference",
          "payment_type",
          "execution_status",
          "export",
          "problems"
        ],
        "title": "PaymentRow"
      },
      "PaymentRunInput": {
        "properties": {
          "payment_date": {
            "type": "string",
            "format": "date",
            "title": "Payment Date",
            "description": "Day the payments are booked (ISO 8601, e.g. `2026-09-30`), today at the latest. The bank pays on the execution date of the payment file, which may be later but not after the cash discount period of a bill whose discount the payment takes."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "GL bank account code; default: per currency, as a payment's default bank account, refused when only a main account in another currency is left."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/RunLine"
            },
            "type": "array",
            "maxItems": 1000,
            "minItems": 1,
            "title": "Lines",
            "description": "The reviewed proposal lines to pay, 1 to 1000 vendor bills with the amount and cash discount of each."
          }
        },
        "type": "object",
        "required": [
          "payment_date",
          "lines"
        ],
        "title": "PaymentRunInput",
        "examples": [
          {
            "bank_account": "1020",
            "lines": [
              {
                "amount": "1176.00",
                "discount": "24.00",
                "document": "BILL-2026-000001"
              }
            ],
            "payment_date": "2026-09-30"
          }
        ]
      },
      "PaymentRunResult": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "payment_date": {
            "type": "string",
            "format": "date",
            "title": "Payment Date",
            "description": "Date of the payments."
          },
          "payments": {
            "items": {
              "$ref": "#/components/schemas/RunPayment"
            },
            "type": "array",
            "title": "Payments",
            "description": "The payments created, one per vendor (a bill with a structured reference on its own)."
          },
          "posted": {
            "type": "integer",
            "title": "Posted",
            "description": "Number of payments posted."
          },
          "pending_approval": {
            "type": "integer",
            "title": "Pending Approval",
            "description": "Number of payments waiting for a second person."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "What to know that did not stop the run, in English: one line per bank account the run takes below zero in the books on the payment date (the money may be there and not booked yet)."
          },
          "warning_reasons": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Warning Reasons",
            "description": "The same by code (`bankBalance.warning.overdrawn`, with `account`, `entity`, `balance`, `after`, `currency` and `on`; `overdrawn_in_transit` adds `in_transit` when payments the bank has not executed yet count towards it), in the order of `warnings`."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "payment_date",
          "payments",
          "posted",
          "pending_approval"
        ],
        "title": "PaymentRunResult"
      },
      "PendingMember": {
        "properties": {
          "approval_id": {
            "type": "string",
            "format": "uuid",
            "title": "Approval Id",
            "description": "The approval request: `POST /v1/approvals/{approval_id}/approve`, by a second person with the `approve` scope."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the subsidiary entity."
          },
          "ownership_percent": {
            "type": "string",
            "title": "Ownership Percent",
            "description": "The proposed share, in percent."
          },
          "consolidated_from": {
            "type": "string",
            "format": "date",
            "title": "Consolidated From",
            "description": "The proposed date it is consolidated from."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who requested it, as an actor object."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "title": "Requested At",
            "description": "When it was requested (UTC)."
          }
        },
        "type": "object",
        "required": [
          "approval_id",
          "entity",
          "ownership_percent",
          "consolidated_from",
          "requested_by",
          "requested_at"
        ],
        "title": "PendingMember"
      },
      "PendingPolicyChange": {
        "properties": {
          "approval_id": {
            "type": "string",
            "title": "Approval Id",
            "description": "The approval request a second administrator decides, or the person who asked withdraws (`POST /v1/approvals/{approval_id}/withdraw`)."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who asked for it, as an actor object."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "title": "Requested At",
            "description": "When it was asked for (ISO 8601, UTC)."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "The comment given with the change; null if none."
          },
          "source": {
            "type": "string",
            "enum": [
              "default",
              "organization"
            ],
            "title": "Source",
            "description": "default (a return to the default table) or organization."
          },
          "relaxed": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Relaxed",
            "description": "What it relaxes, at most 20, e.g. `human change_posting_limit: require_approval -> allow`."
          },
          "relaxed_count": {
            "type": "integer",
            "title": "Relaxed Count",
            "description": "How many decisions it relaxes in all."
          }
        },
        "type": "object",
        "required": [
          "approval_id",
          "requested_by",
          "requested_at",
          "comment",
          "source",
          "relaxed",
          "relaxed_count"
        ],
        "title": "PendingPolicyChange"
      },
      "PendingRequest": {
        "properties": {
          "approval_id": {
            "type": "string",
            "format": "uuid",
            "title": "Approval Id",
            "description": "Id of the approval request; decide it with `POST /v1/approvals/{id}/approve` or `reject`."
          },
          "action": {
            "type": "string",
            "title": "Action",
            "description": "activate_party, change_bank_details, change_party_details or change_party_status."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "The actor (`type`, `id`) that asked."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "title": "Requested At",
            "description": "When it was requested (UTC)."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why a second person is needed."
          },
          "current": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current",
            "description": "The values now (changes)."
          },
          "proposed": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proposed",
            "description": "The values once approved (changes)."
          }
        },
        "type": "object",
        "required": [
          "approval_id",
          "action",
          "requested_by",
          "requested_at",
          "reason"
        ],
        "title": "PendingRequest"
      },
      "PeriodOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the period."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year of the period."
          },
          "number": {
            "type": "integer",
            "title": "Number",
            "description": "The period number in the year, from 1; adjustment periods follow the regular ones."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`regular`, or `adjustment` for a one-day closing period on the last day of the year."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "First day of the period (ISO 8601)."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "Last day of the period (ISO 8601)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`open` (entries may be posted) or `closed`."
          },
          "closed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed At",
            "description": "When the period was closed (ISO 8601, UTC); null while open."
          },
          "closed_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed By",
            "description": "Id of the actor that closed the period; null while open."
          }
        },
        "type": "object",
        "required": [
          "id",
          "fiscal_year",
          "number",
          "kind",
          "start_date",
          "end_date",
          "status",
          "closed_at",
          "closed_by"
        ],
        "title": "PeriodOut"
      },
      "PeriodProfitAndLoss": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency all amounts are in: the entity's functional currency, or the one asked for with `currency`."
          },
          "period": {
            "$ref": "#/components/schemas/PeriodRef",
            "description": "The period reported."
          },
          "current": {
            "$ref": "#/components/schemas/ProfitAndLoss",
            "description": "The period's own postings."
          },
          "year_to_date": {
            "$ref": "#/components/schemas/ProfitAndLoss",
            "description": "From the start of the fiscal year through the period."
          },
          "prior_period": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PeriodRef"
              },
              {
                "type": "null"
              }
            ],
            "description": "The same period number of the previous fiscal year; null if none."
          },
          "prior_current": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProfitAndLoss"
              },
              {
                "type": "null"
              }
            ],
            "description": "The comparative period's own postings; null without comparative."
          },
          "prior_year_to_date": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProfitAndLoss"
              },
              {
                "type": "null"
              }
            ],
            "description": "The comparative year to date; null without comparative."
          },
          "notes": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Notes",
            "description": "Caveats (`reportNote` codes), e.g. that no comparative period exists or that the periods differ in length."
          },
          "translation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportTranslation"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shown in another currency than the entity's own: how it was translated and the rates used; null in the entity's own currency."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "period",
          "current",
          "year_to_date",
          "prior_period",
          "prior_current",
          "prior_year_to_date",
          "notes"
        ],
        "title": "PeriodProfitAndLoss"
      },
      "PeriodRef": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the fiscal period."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year of the period."
          },
          "number": {
            "type": "integer",
            "title": "Number",
            "description": "The period number in the year, from 1; adjustment periods follow the regular ones."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`regular`, or `adjustment` for a one-day closing period on the last day of the year."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the period (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the period (ISO 8601)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`open` (entries may be posted) or `closed`."
          }
        },
        "type": "object",
        "required": [
          "id",
          "fiscal_year",
          "number",
          "kind",
          "start",
          "end",
          "status"
        ],
        "title": "PeriodRef"
      },
      "PeriodState": {
        "properties": {
          "period_id": {
            "type": "string",
            "format": "uuid",
            "title": "Period Id",
            "description": "Id (uuid) of the period."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "Label of the period, e.g. `2026-09`."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`open` or `closed`, after this turn."
          },
          "ready": {
            "type": "boolean",
            "title": "Ready",
            "description": "True when the close checklist passes, after this turn."
          },
          "actions": {
            "items": {
              "$ref": "#/components/schemas/CloseAction"
            },
            "type": "array",
            "title": "Actions",
            "description": "The open steps that only a person can take, each with where to take it."
          }
        },
        "type": "object",
        "required": [
          "period_id",
          "period",
          "status",
          "ready",
          "actions"
        ],
        "title": "PeriodState"
      },
      "PeriodTrialBalance": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; all amounts are in it."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The last day of the period (ISO 8601)."
          },
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/AccountBalance"
            },
            "type": "array",
            "title": "Accounts",
            "description": "One row per account with postings through the period, ordered by code."
          },
          "total_debit": {
            "type": "string",
            "title": "Total Debit",
            "description": "Sum of the debit column."
          },
          "total_credit": {
            "type": "string",
            "title": "Total Credit",
            "description": "Sum of the credit column."
          },
          "balanced": {
            "type": "boolean",
            "title": "Balanced",
            "description": "True when total debit equals total credit."
          },
          "period": {
            "$ref": "#/components/schemas/PeriodRef",
            "description": "The period the trial balance is through."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "as_of",
          "accounts",
          "total_debit",
          "total_credit",
          "balanced",
          "period"
        ],
        "title": "PeriodTrialBalance"
      },
      "Person": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The user's id (`GET /v1/people`)."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "Their e-mail address."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Their name."
          }
        },
        "type": "object",
        "required": [
          "id",
          "email",
          "name"
        ],
        "title": "Person"
      },
      "PersonAccess": {
        "properties": {
          "person": {
            "$ref": "#/components/schemas/Person",
            "description": "The person."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`invited`, `active` or `disabled`."
          },
          "record_visibility": {
            "type": "string",
            "enum": [
              "all",
              "own",
              "team"
            ],
            "title": "Record Visibility",
            "description": "Which sales records the person sees: `all` (every customer, contact, deal and activity), `team` (the records they or anyone in a team of theirs own) or `own` (the records they own)."
          },
          "teams": {
            "items": {
              "$ref": "#/components/schemas/SalesTeamRef"
            },
            "type": "array",
            "title": "Teams",
            "description": "The sales teams they are in."
          }
        },
        "type": "object",
        "required": [
          "person",
          "status",
          "record_visibility",
          "teams"
        ],
        "title": "PersonAccess"
      },
      "PersonAccessOut": {
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid",
            "title": "User Id",
            "description": "Id of the person."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Their name; null when they gave none."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The address they sign in with."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`invited`, `active` or `disabled`."
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "The role given with `PUT /v1/roles/people/{user_id}`; null for a person whose rights were set otherwise (on Settings, Users)."
          },
          "role_title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role Title",
            "description": "The role's name; null: no role."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "Its rights: `read` always, and any of `draft`, `post`, `approve`, `audit`, `admin` (`admin` holds every right and opens every area)."
          },
          "areas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Areas",
            "description": "The areas the person opens; null: every area."
          },
          "visibility": {
            "type": "string",
            "enum": [
              "all",
              "own",
              "team"
            ],
            "title": "Visibility",
            "description": "Which sales records its people see: `all`, `team` (their sales teams') or `own` (theirs)."
          },
          "differs": {
            "type": "boolean",
            "title": "Differs",
            "description": "True when the person's rights or areas are no longer their role's (their rights were changed since, or the own role was)."
          },
          "last_used": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Used",
            "description": "The last day the person (or a key acting for them) used the app; null: not since use is counted."
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "name",
          "email",
          "status",
          "role",
          "scopes",
          "areas",
          "visibility",
          "differs",
          "last_used"
        ],
        "title": "PersonAccessOut"
      },
      "Pipeline": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "closed_from": {
            "type": "string",
            "format": "date",
            "title": "Closed From",
            "description": "First day of the range of `closed`."
          },
          "closed_to": {
            "type": "string",
            "format": "date",
            "title": "Closed To",
            "description": "Last day of the range of `closed`."
          },
          "open": {
            "items": {
              "$ref": "#/components/schemas/StageTotal"
            },
            "type": "array",
            "title": "Open",
            "description": "The open opportunities by stage (in pipeline order) and currency. Amounts are summed per currency and never converted."
          },
          "closed": {
            "items": {
              "$ref": "#/components/schemas/StageTotal"
            },
            "type": "array",
            "title": "Closed",
            "description": "The opportunities won and lost in the range, by stage and currency."
          },
          "open_tasks": {
            "type": "integer",
            "title": "Open Tasks",
            "description": "Tasks of the entity not done yet."
          },
          "overdue_tasks": {
            "type": "integer",
            "title": "Overdue Tasks",
            "description": "Of them, those whose due day has passed."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "closed_from",
          "closed_to",
          "open",
          "closed",
          "open_tasks",
          "overdue_tasks"
        ],
        "title": "Pipeline",
        "examples": [
          {
            "closed": [
              {
                "amount": "12000.00",
                "count": 1,
                "currency": "CHF",
                "stage": "won",
                "weighted_amount": "12000.00"
              }
            ],
            "closed_from": "2026-01-01",
            "closed_to": "2026-10-04",
            "entity": "CH01",
            "open": [
              {
                "amount": "30000.00",
                "count": 2,
                "currency": "CHF",
                "stage": "proposal",
                "weighted_amount": "15000.00"
              }
            ],
            "open_tasks": 3,
            "overdue_tasks": 1
          }
        ]
      },
      "PipelineReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The report's currency (the entity's functional one)."
          },
          "rate_day": {
            "type": "string",
            "format": "date",
            "title": "Rate Day",
            "description": "The day whose ECB fixing converts the amounts."
          },
          "fixing_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fixing Date",
            "description": "The fixing used; null when there is none near the day (then every other currency is in `unconverted`)."
          },
          "unconverted": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unconverted",
            "description": "Currencies left out of the converted amounts."
          },
          "today": {
            "type": "string",
            "format": "date",
            "title": "Today",
            "description": "Today where the entity is."
          },
          "by_owner": {
            "items": {
              "$ref": "#/components/schemas/PipelineRow"
            },
            "type": "array",
            "title": "By Owner",
            "description": "Open deals by owner, the largest first."
          },
          "by_stage": {
            "items": {
              "$ref": "#/components/schemas/PipelineRow"
            },
            "type": "array",
            "title": "By Stage",
            "description": "Open deals by stage, in pipeline order."
          },
          "by_month": {
            "items": {
              "$ref": "#/components/schemas/PipelineRow"
            },
            "type": "array",
            "title": "By Month",
            "description": "Open deals by the month they are expected to close, the earliest first; `none` last."
          },
          "total": {
            "$ref": "#/components/schemas/PipelineRow",
            "description": "All open deals."
          },
          "late": {
            "type": "integer",
            "title": "Late",
            "description": "Open deals whose expected close day has passed."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "rate_day",
          "fixing_date",
          "unconverted",
          "today",
          "by_owner",
          "by_stage",
          "by_month",
          "total",
          "late"
        ],
        "title": "PipelineReport",
        "examples": [
          {
            "by_month": [],
            "by_owner": [
              {
                "amount": {
                  "amount": "42870.00",
                  "by_currency": [
                    {
                      "amount": "30000.00",
                      "currency": "CHF"
                    },
                    {
                      "amount": "13700.00",
                      "currency": "EUR"
                    }
                  ]
                },
                "count": 3,
                "key": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                "owner": {
                  "email": "lena@example.com",
                  "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
                  "name": "Lena Meier"
                },
                "weighted": {
                  "amount": "19040.00",
                  "by_currency": [
                    {
                      "amount": "13000.00",
                      "currency": "CHF"
                    },
                    {
                      "amount": "6165.00",
                      "currency": "EUR"
                    }
                  ]
                }
              }
            ],
            "by_stage": [],
            "currency": "CHF",
            "entity": "CH01",
            "fixing_date": "2026-10-23",
            "late": 1,
            "rate_day": "2026-10-23",
            "today": "2026-10-23",
            "total": {
              "amount": {
                "amount": "42870.00",
                "by_currency": [
                  {
                    "amount": "30000.00",
                    "currency": "CHF"
                  },
                  {
                    "amount": "13700.00",
                    "currency": "EUR"
                  }
                ]
              },
              "count": 3,
              "key": "total",
              "weighted": {
                "amount": "19040.00",
                "by_currency": [
                  {
                    "amount": "13000.00",
                    "currency": "CHF"
                  },
                  {
                    "amount": "6165.00",
                    "currency": "EUR"
                  }
                ]
              }
            },
            "unconverted": []
          }
        ]
      },
      "PipelineRow": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "What the row groups: an owner's user id (`none` for no owner), a stage, or a month `YYYY-MM` of the expected close (`none` for no date)."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "The owner (rows by owner)."
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "How many open deals."
          },
          "amount": {
            "$ref": "#/components/schemas/Figure",
            "description": "Their expected value."
          },
          "weighted": {
            "$ref": "#/components/schemas/Figure",
            "description": "Their value weighted by probability."
          }
        },
        "type": "object",
        "required": [
          "key",
          "count",
          "amount",
          "weighted"
        ],
        "title": "PipelineRow"
      },
      "PlanDetail": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Plan id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The plan's name."
          },
          "kind": {
            "type": "string",
            "enum": [
              "budget",
              "forecast"
            ],
            "title": "Kind",
            "description": "`budget` or `forecast`."
          },
          "fiscal_year": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fiscal Year",
            "description": "The fiscal year of a budget."
          },
          "horizon": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Horizon",
            "description": "How many periods a forecast looks ahead."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The functional currency its amounts are in."
          },
          "current_version_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Version Id",
            "description": "The approved version, the one reports compare with; empty before the first approval."
          },
          "versions": {
            "type": "integer",
            "title": "Versions",
            "description": "How many versions it has."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "version_list": {
            "items": {
              "$ref": "#/components/schemas/VersionOut"
            },
            "type": "array",
            "title": "Version List",
            "description": "Every version, the newest first."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "name",
          "kind",
          "fiscal_year",
          "horizon",
          "currency",
          "current_version_id",
          "versions",
          "created_by",
          "created_at",
          "version_list"
        ],
        "title": "PlanDetail",
        "examples": [
          {
            "created_at": "2026-10-01T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "current_version_id": "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607",
            "entity": "CH01",
            "fiscal_year": 2027,
            "id": "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6",
            "kind": "budget",
            "name": "Budget 2027",
            "versions": 2
          }
        ]
      },
      "PlanInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity the plan is for."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What the plan is called, unique within the entity, e.g. `Budget 2027`."
          },
          "kind": {
            "type": "string",
            "enum": [
              "budget",
              "forecast"
            ],
            "title": "Kind",
            "description": "`budget` (the figures of one fiscal year, fixed once approved) or `forecast` (a number of periods ahead, rolled forward as periods close)."
          },
          "fiscal_year": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 2999.0,
                "minimum": 1900.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Fiscal Year",
            "description": "The fiscal year of a budget (required for a budget, not allowed for a forecast). Its periods must exist (`POST /v1/entities/{entity}/fiscal-years`)."
          },
          "horizon": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 24.0,
                "minimum": 3.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Horizon",
            "description": "How many periods a forecast looks ahead, 3 to 24 (default 12); not allowed for a budget."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name",
          "kind"
        ],
        "title": "PlanInput",
        "examples": [
          {
            "entity": "CH01",
            "fiscal_year": 2027,
            "kind": "budget",
            "name": "Budget 2027"
          },
          {
            "entity": "CH01",
            "horizon": 12,
            "kind": "forecast",
            "name": "Rolling forecast"
          }
        ]
      },
      "PlanLineInput": {
        "properties": {
          "account": {
            "type": "string",
            "maxLength": 50,
            "minLength": 1,
            "title": "Account",
            "description": "Code of a revenue or expense account."
          },
          "period": {
            "type": "string",
            "pattern": "^\\d{4}-\\d{2}$",
            "title": "Period",
            "description": "The regular period as `YYYY-NN` (fiscal year and period number), as the close checklist names it, e.g. `2027-03`."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,16}|(?=[\\d.]{1,17}0*$)\\d*\\.\\d*0*$)"
              }
            ],
            "title": "Amount",
            "description": "The planned amount in the entity's functional currency, as a decimal string, in the account's natural direction: revenue as a positive credit, expenses as a positive debit (as the profit and loss shows them). A negative amount is a reduction. At most the currency's minor units (2 decimals for CHF and EUR); at most 16 digits in all."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A note on the amount."
          }
        },
        "type": "object",
        "required": [
          "account",
          "period",
          "amount"
        ],
        "title": "PlanLineInput"
      },
      "PlanLineOut": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "Account name."
          },
          "account_type": {
            "type": "string",
            "enum": [
              "expense",
              "revenue"
            ],
            "title": "Account Type",
            "description": "`revenue` or `expense`."
          },
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The account's report line, e.g. `pl.revenue`."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The planned amount in the functional currency."
          },
          "method": {
            "type": "string",
            "enum": [
              "actual",
              "manual",
              "prior_year",
              "run_rate",
              "schedule"
            ],
            "title": "Method",
            "description": "How the amount was made: `manual` (entered); a rolled forecast's lines also `actual`, `run_rate`, `prior_year` or `schedule`."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "The note on the amount."
          }
        },
        "type": "object",
        "required": [
          "account",
          "account_name",
          "account_type",
          "report_line",
          "period",
          "amount",
          "method",
          "note"
        ],
        "title": "PlanLineOut"
      },
      "PlanOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Plan id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The plan's name."
          },
          "kind": {
            "type": "string",
            "enum": [
              "budget",
              "forecast"
            ],
            "title": "Kind",
            "description": "`budget` or `forecast`."
          },
          "fiscal_year": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fiscal Year",
            "description": "The fiscal year of a budget."
          },
          "horizon": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Horizon",
            "description": "How many periods a forecast looks ahead."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The functional currency its amounts are in."
          },
          "current_version_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current Version Id",
            "description": "The approved version, the one reports compare with; empty before the first approval."
          },
          "versions": {
            "type": "integer",
            "title": "Versions",
            "description": "How many versions it has."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "name",
          "kind",
          "fiscal_year",
          "horizon",
          "currency",
          "current_version_id",
          "versions",
          "created_by",
          "created_at"
        ],
        "title": "PlanOut",
        "examples": [
          {
            "created_at": "2026-10-01T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "current_version_id": "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607",
            "entity": "CH01",
            "fiscal_year": 2027,
            "id": "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6",
            "kind": "budget",
            "name": "Budget 2027",
            "versions": 2
          }
        ]
      },
      "PlanRename": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "The plan's new name."
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "PlanRename",
        "examples": [
          {
            "name": "Budget 2027 (board)"
          }
        ]
      },
      "PlanTotals": {
        "properties": {
          "revenue": {
            "type": "string",
            "title": "Revenue",
            "description": "Planned revenue (the lines of revenue accounts)."
          },
          "expenses": {
            "type": "string",
            "title": "Expenses",
            "description": "Planned expenses (the lines of expense accounts)."
          },
          "net": {
            "type": "string",
            "title": "Net",
            "description": "Revenue less expenses."
          }
        },
        "type": "object",
        "required": [
          "revenue",
          "expenses",
          "net"
        ],
        "title": "PlanTotals"
      },
      "PlatformAuditOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the record."
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "title": "At",
            "description": "When (ISO 8601, UTC)."
          },
          "action": {
            "type": "string",
            "title": "Action",
            "description": "What was done: `operator.sign_in`, `operator.sign_in_denied`, `operator.sign_out`, `org.provision`, `org.suspend`, `org.reactivate`, `org.mark_demo`, `org.mark_demo_refused`, `org.mark_customer`, `org.delete`, `org.delete_refused`, `org.delete_undone`, `org.purge_demo`, `org.invite_admin`, `org.reshow_invite`, `org.passkey_reset`, `org.view`, `platform.choose_models`, `platform.check_model`."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "denied",
              "failed",
              "ok",
              "refused"
            ],
            "title": "Outcome",
            "description": "`ok`, `denied` (not allowed to), `refused` (a guard said no) or `failed`."
          },
          "actor": {
            "additionalProperties": true,
            "type": "object",
            "title": "Actor",
            "description": "Who: `type`, `id` and `name`, and `email` for an operator."
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Address",
            "description": "The client address; null for the command line."
          },
          "org_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Org Id",
            "description": "The organization it concerns, if any."
          },
          "org_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Org Name",
            "description": "Its name when it happened."
          },
          "detail": {
            "additionalProperties": true,
            "type": "object",
            "title": "Detail",
            "description": "What else is worth knowing; never a secret."
          }
        },
        "type": "object",
        "required": [
          "id",
          "at",
          "action",
          "outcome",
          "actor",
          "address",
          "org_id",
          "org_name",
          "detail"
        ],
        "title": "PlatformAuditOut"
      },
      "PolicyInput": {
        "properties": {
          "table": {
            "$ref": "#/components/schemas/PolicyTable",
            "description": "A decision table with inputs actor_type, action, amount and source and a decision output (allow, require_approval or deny); first hit wins. Start from GET /v1/approval-policy."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "Why the policy changes, up to 1000 characters; kept with the version and in the audit event."
          }
        },
        "type": "object",
        "required": [
          "table"
        ],
        "title": "PolicyInput",
        "examples": [
          {
            "comment": "Human postings above 250000 need approval",
            "table": {
              "description": "Agents may only post; their manual and large postings are reviewed. Humans may post directly, but a posting above 250000 needs a second person.",
              "domain": "erp.policy",
              "hit_policy": "first",
              "id": "org.approval-policy",
              "inputs": [
                {
                  "name": "actor_type",
                  "type": "enum",
                  "values": [
                    "human",
                    "agent",
                    "system"
                  ]
                },
                {
                  "name": "action",
                  "type": "enum",
                  "values": [
                    "post",
                    "approve",
                    "close_period",
                    "reopen_period",
                    "manage_accounts",
                    "manage_keys",
                    "release_payments",
                    "finalize_vat_return",
                    "activate_party",
                    "change_bank_details",
                    "change_party_details"
                  ]
                },
                {
                  "description": "Total debits of the entry in functional currency.",
                  "name": "amount",
                  "type": "number"
                },
                {
                  "description": "manual, ar, ap, fa, bank, ...",
                  "name": "source",
                  "type": "string"
                }
              ],
              "name": "Demo AG approval policy",
              "outputs": [
                {
                  "description": "allow | require_approval | deny",
                  "name": "decision"
                },
                {
                  "name": "reason"
                }
              ],
              "rules": [
                {
                  "id": "agents_only_post",
                  "then": {
                    "decision": "deny",
                    "reason": "Agents may only post."
                  },
                  "when": {
                    "action": {
                      "not_in": [
                        "post"
                      ]
                    },
                    "actor_type": "agent"
                  }
                },
                {
                  "id": "agent_manual_journals",
                  "then": {
                    "decision": "require_approval",
                    "reason": "Agent journals are reviewed."
                  },
                  "when": {
                    "actor_type": "agent",
                    "source": "manual"
                  }
                },
                {
                  "id": "agent_large_postings",
                  "then": {
                    "decision": "require_approval",
                    "reason": "Agent postings above 5000."
                  },
                  "when": {
                    "actor_type": "agent",
                    "amount": {
                      "gt": 5000
                    }
                  }
                },
                {
                  "id": "agent_routine_postings",
                  "then": {
                    "decision": "allow",
                    "reason": "Routine subledger posting."
                  },
                  "when": {
                    "actor_type": "agent"
                  }
                },
                {
                  "id": "system_allowed",
                  "then": {
                    "decision": "allow",
                    "reason": "System processes run under their own controls."
                  },
                  "when": {
                    "actor_type": "system"
                  }
                },
                {
                  "id": "new_vendors_need_a_second_person",
                  "then": {
                    "decision": "require_approval",
                    "reason": "A new vendor needs a second person."
                  },
                  "when": {
                    "action": "activate_party",
                    "actor_type": "human",
                    "source": "vendor"
                  }
                },
                {
                  "id": "human_large_postings",
                  "then": {
                    "decision": "require_approval",
                    "reason": "Postings above 250000."
                  },
                  "when": {
                    "action": "post",
                    "actor_type": "human",
                    "amount": {
                      "gt": 250000
                    }
                  }
                },
                {
                  "id": "humans_allowed",
                  "then": {
                    "decision": "allow",
                    "reason": "Human with the required scope."
                  },
                  "when": {
                    "actor_type": "human"
                  }
                }
              ],
              "sources": [
                {
                  "authority": "Demo AG",
                  "url": "https://example.com/policies/approval"
                }
              ]
            }
          }
        ]
      },
      "PolicyOut": {
        "properties": {
          "receipt_limit": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receipt Limit",
            "description": "A receipt above this, in the company's currency, waits for a person; null: no limit."
          },
          "category_limits": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Category Limits",
            "description": "Lower limits per expense account code, e.g. meals `{\"6640\": \"80.00\"}`."
          },
          "max_age_days": {
            "type": "integer",
            "maximum": 3660.0,
            "minimum": 1.0,
            "title": "Max Age Days",
            "description": "A receipt older than this waits for a person.",
            "default": 90
          },
          "project_over": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Over",
            "description": "Above this amount an expense names a project or waits; null: never asked."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The company's currency, of the limits."
          },
          "default": {
            "type": "boolean",
            "title": "Default",
            "description": "True: the company has not set its own policy yet."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "default"
        ],
        "title": "PolicyOut",
        "examples": [
          {
            "category_limits": {
              "6640": "80.00"
            },
            "max_age_days": 60,
            "receipt_limit": "500.00"
          }
        ]
      },
      "PolicyResult": {
        "properties": {
          "decision": {
            "type": "string",
            "enum": [
              "allow",
              "deny",
              "require_approval"
            ],
            "title": "Decision",
            "description": "`allow` (go ahead), `require_approval` (a second person must approve) or `deny` (refused)."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "The reason text of the rule that decided."
          },
          "rule_id": {
            "type": "string",
            "title": "Rule Id",
            "description": "Id of the rule that decided, or `none` when no rule matched (a denial)."
          },
          "table_id": {
            "type": "string",
            "title": "Table Id",
            "description": "Id of the decision table that was applied."
          }
        },
        "type": "object",
        "required": [
          "decision",
          "reason",
          "rule_id",
          "table_id"
        ],
        "title": "PolicyResult"
      },
      "PolicyTable": {
        "properties": {
          "published_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Published At",
            "description": "When this record entered the dataset."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When its content last changed after publication."
          },
          "sources": {
            "items": {
              "$ref": "#/components/schemas/Source"
            },
            "type": "array",
            "minItems": 1,
            "title": "Sources",
            "description": "Where the rules come from (at least one), e.g. the company's own policy document."
          },
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Identifier of the table, e.g. `org.approval-policy`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Human-readable name."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the table decides, in a sentence or two."
          },
          "domain": {
            "type": "string",
            "title": "Domain",
            "description": "e.g. 'tax.indirect', 'standards.us_gaap'."
          },
          "hit_policy": {
            "type": "string",
            "enum": [
              "collect",
              "first"
            ],
            "title": "Hit Policy",
            "description": "`first`: the first rule whose conditions all match decides (use this for the approval policy). `collect`: every matching rule is returned.",
            "default": "first"
          },
          "inputs": {
            "items": {
              "$ref": "#/components/schemas/PolicyTableInput"
            },
            "type": "array",
            "title": "Inputs",
            "description": "The inputs rules can test. An approval policy declares exactly `actor_type`, `action`, `amount` and `source`, as in `GET /v1/approval-policy`."
          },
          "outputs": {
            "items": {
              "$ref": "#/components/schemas/PolicyTableOutput"
            },
            "type": "array",
            "title": "Outputs",
            "description": "What a rule yields. An approval policy declares `decision` and `reason`."
          },
          "rules": {
            "items": {
              "$ref": "#/components/schemas/PolicyTableRule"
            },
            "type": "array",
            "minItems": 1,
            "title": "Rules",
            "description": "The rules, tried in order. A rule's `when` maps an input to a literal or an operator map (`in`, `not_in`, `ne`, `gt`, `gte`, `lt`, `lte`); an input left out matches anything."
          },
          "limitations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Limitations",
            "description": "Known gaps of the table, as sentences; may be empty."
          }
        },
        "type": "object",
        "required": [
          "sources",
          "id",
          "name",
          "description",
          "domain",
          "inputs",
          "outputs",
          "rules"
        ],
        "title": "PolicyTable"
      },
      "PolicyTableInput": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Input name; for an approval policy one of `actor_type`, `action`, `amount`, `source`."
          },
          "type": {
            "type": "string",
            "enum": [
              "boolean",
              "enum",
              "number",
              "string"
            ],
            "title": "Type",
            "description": "`string`, `boolean`, `number` or `enum`; an approval policy needs `enum` for `actor_type` and `action`, `number` for `amount`, `string` for `source`."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What the input means; optional."
          },
          "values": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Values",
            "description": "Allowed values for enum inputs."
          },
          "required": {
            "type": "boolean",
            "title": "Required",
            "description": "Whether callers must supply the input; default true.",
            "default": true
          },
          "default": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "boolean"
              },
              {
                "type": "integer"
              },
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Default",
            "description": "Value used when an optional input is not supplied."
          }
        },
        "type": "object",
        "required": [
          "name",
          "type"
        ],
        "title": "PolicyTableInput"
      },
      "PolicyTableOutput": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Output name; an approval policy needs `decision` (`allow`, `require_approval` or `deny`) and usually `reason`."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What the output means; optional."
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "PolicyTableOutput"
      },
      "PolicyTableRule": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Unique id of the rule within the table; returned with each decision as `rule_id`."
          },
          "when": {
            "additionalProperties": true,
            "type": "object",
            "title": "When",
            "description": "Conditions on the inputs, e.g. `{\"actor_type\": \"human\", \"amount\": {\"gt\": 250000}}`. Every condition must hold; an empty object always matches."
          },
          "then": {
            "additionalProperties": true,
            "type": "object",
            "title": "Then",
            "description": "The outputs when the rule matches, e.g. `{\"decision\": \"allow\", \"reason\": \"...\"}`; `decision` must be `allow`, `require_approval` or `deny`."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Where the rule comes from, e.g. a policy clause; optional."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A remark on the rule; optional."
          }
        },
        "type": "object",
        "required": [
          "id",
          "then"
        ],
        "title": "PolicyTableRule"
      },
      "PolicyUpdate": {
        "properties": {
          "receipt_limit": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receipt Limit",
            "description": "A receipt above this, in the company's currency, waits for a person; null: no limit."
          },
          "category_limits": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "string",
                  "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
                }
              ]
            },
            "type": "object",
            "title": "Category Limits",
            "description": "Lower limits per expense account code, e.g. meals `{\"6640\": \"80.00\"}`."
          },
          "max_age_days": {
            "type": "integer",
            "maximum": 3660.0,
            "minimum": 1.0,
            "title": "Max Age Days",
            "description": "A receipt older than this waits for a person.",
            "default": 90
          },
          "project_over": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Project Over",
            "description": "Above this amount an expense names a project or waits; null: never asked."
          }
        },
        "type": "object",
        "title": "PolicyUpdate",
        "examples": [
          {
            "category_limits": {
              "6640": "80.00"
            },
            "max_age_days": 60,
            "receipt_limit": "500.00"
          }
        ]
      },
      "PolicyVersionOut": {
        "properties": {
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "Version number, from 1."
          },
          "source": {
            "type": "string",
            "enum": [
              "default",
              "organization"
            ],
            "title": "Source",
            "description": "`organization`, or `default` for a reset to the default policy."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "The comment given with this version; null if none."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made the version, as an actor object."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was made (ISO 8601, UTC)."
          },
          "table": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PolicyTable"
              },
              {
                "type": "null"
              }
            ],
            "description": "null: the default policy."
          }
        },
        "type": "object",
        "required": [
          "version",
          "source",
          "comment",
          "created_by",
          "created_at",
          "table"
        ],
        "title": "PolicyVersionOut"
      },
      "PossibleDuplicate": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the other customer or vendor."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Its code, e.g. `V-ALP`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its legal name."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Its status: `draft`, `active`, `blocked` or `inactive`."
          },
          "same": {
            "items": {
              "type": "string",
              "enum": [
                "iban",
                "name",
                "vat_number"
              ]
            },
            "type": "array",
            "title": "Same",
            "description": "What both have in common: the VAT number (compared as a registration), an IBAN, or the name (case, punctuation and legal forms such as AG or GmbH ignored)."
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "The warning in words, e.g. `Possible duplicate of V-ALP Alpen Werkzeug AG: same VAT number and IBAN`."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "name",
          "status",
          "same",
          "message"
        ],
        "title": "PossibleDuplicate",
        "description": "Another customer or vendor of the same company this one may duplicate."
      },
      "PostLineInput": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Counter account, e.g. bank fees or interest income."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Entry description. Default: the line's remittance text, else its reference."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "Cost centre, profit centre or project of the counter line, by dimension code: `{\"cost_centre\": \"CC-200\"}` (`GET /v1/dimensions`); active values valid on the booking date only."
          },
          "on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "On",
            "description": "Posting date, ISO 8601: a day in an open period, not before the line's booking date (422 `bank_posting_before_line`). Default: the booking date, or when its period is closed the first day of the next open period (the line's `posting_date`). The line keeps its booking date on the statement."
          }
        },
        "type": "object",
        "required": [
          "account"
        ],
        "title": "PostLineInput",
        "examples": [
          {
            "account": "6940",
            "description": "Bank fees September 2026"
          }
        ]
      },
      "PostalAddress": {
        "properties": {
          "line1": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line1",
            "description": "BT-35 / BT-50 / BT-75"
          },
          "line2": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line2",
            "description": "BT-36 / BT-51 / BT-76"
          },
          "line3": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line3",
            "description": "BT-162 / BT-163 / BT-165"
          },
          "city": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "City",
            "description": "BT-37 / BT-52 / BT-77"
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "BT-38 / BT-53 / BT-78"
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "BT-39 / BT-54 / BT-79"
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "BT-40 / BT-55 / BT-80"
          }
        },
        "type": "object",
        "title": "PostalAddress"
      },
      "PostalTown": {
        "properties": {
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "The town of the postal code; null where only its state is known (US)."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "The canton or state as an ISO 3166-2 code (`CH-ZH`, `US-CA`) where the address forms pick it from a list (CH, DE, AT, US); else null."
          }
        },
        "type": "object",
        "required": [
          "town",
          "subdivision"
        ],
        "title": "PostalTown"
      },
      "PostalTownsOut": {
        "properties": {
          "country": {
            "type": "string",
            "title": "Country",
            "description": "The country asked, ISO 3166-1 alpha-2."
          },
          "postal_code": {
            "type": "string",
            "title": "Postal Code",
            "description": "The postal code asked, as given."
          },
          "towns": {
            "items": {
              "$ref": "#/components/schemas/PostalTown"
            },
            "type": "array",
            "title": "Towns",
            "description": "The towns the postal code covers, by name (one for most; several where a code serves several villages); empty for an unknown code or a country without a list."
          }
        },
        "type": "object",
        "required": [
          "country",
          "postal_code",
          "towns"
        ],
        "title": "PostalTownsOut"
      },
      "PostingLimitRequest": {
        "properties": {
          "approval_id": {
            "type": "string",
            "format": "uuid",
            "title": "Approval Id",
            "description": "Id (uuid) of the approval request; a second person approves it (`POST /v1/approvals/{approval_id}/approve`), or the person who asked withdraws it (`POST /v1/approvals/{approval_id}/withdraw`)."
          },
          "current": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Current",
            "description": "The limit now, which holds until then; null: none."
          },
          "proposed": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Proposed",
            "description": "The limit once approved; null: no limit."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who asked (`type`, `id`, `name`)."
          },
          "requested_at": {
            "type": "string",
            "format": "date-time",
            "title": "Requested At",
            "description": "When it was asked (UTC)."
          }
        },
        "type": "object",
        "required": [
          "approval_id",
          "current",
          "proposed",
          "requested_by",
          "requested_at"
        ],
        "title": "PostingLimitRequest",
        "description": "A request to raise or remove the posting approval limit that waits for a second person."
      },
      "PrecedingInvoice": {
        "properties": {
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "BT-25"
          },
          "issue_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Issue Date",
            "description": "BT-26"
          }
        },
        "type": "object",
        "title": "PrecedingInvoice",
        "description": "BG-3."
      },
      "Preferences": {
        "properties": {
          "locale": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de-CH",
                  "en",
                  "fr-CH",
                  "it-CH",
                  "sv-SE"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Locale",
            "description": "UI language; null follows the browser's language."
          }
        },
        "type": "object",
        "title": "Preferences",
        "examples": [
          {
            "locale": "de-CH"
          }
        ]
      },
      "PresentationItem": {
        "properties": {
          "contract": {
            "type": "string",
            "title": "Contract",
            "description": "Number of the revenue contract."
          },
          "contract_id": {
            "type": "string",
            "format": "uuid",
            "title": "Contract Id",
            "description": "Id of the revenue contract."
          },
          "position": {
            "type": "string",
            "title": "Position",
            "description": "Revenue recognised less billed at the period end, in the functional currency: positive is a debit position (presented as an asset), negative a contract liability (presented where it is)."
          },
          "caption": {
            "type": "string",
            "enum": [
              "contract_asset",
              "unbilled_receivable"
            ],
            "title": "Caption",
            "description": "Where a debit position is presented: `unbilled_receivable` when only time must pass before payment is due (the contract's `right_to_consideration` `unconditional`), else `contract_asset`."
          },
          "presented": {
            "type": "string",
            "title": "Presented",
            "description": "What the period's entries present after this run."
          },
          "change": {
            "type": "string",
            "title": "Change",
            "description": "What this run posts (or would post) for the contract."
          }
        },
        "type": "object",
        "required": [
          "contract",
          "contract_id",
          "position",
          "caption",
          "presented",
          "change"
        ],
        "title": "PresentationItem"
      },
      "PreviewOut": {
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid",
            "title": "User Id",
            "description": "Id of the person."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Their name; null when they gave none."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The address they sign in with."
          },
          "role_title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role Title",
            "description": "Their role's name; null: no role."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "Its rights: `read` always, and any of `draft`, `post`, `approve`, `audit`, `admin` (`admin` holds every right and opens every area)."
          },
          "areas": {
            "items": {
              "$ref": "#/components/schemas/AreaOut"
            },
            "type": "array",
            "title": "Areas",
            "description": "The areas the person opens."
          },
          "closed_areas": {
            "items": {
              "$ref": "#/components/schemas/AreaOut"
            },
            "type": "array",
            "title": "Closed Areas",
            "description": "The areas they do not open."
          },
          "visibility": {
            "type": "string",
            "enum": [
              "all",
              "own",
              "team"
            ],
            "title": "Visibility",
            "description": "Which sales records its people see: `all`, `team` (their sales teams') or `own` (theirs)."
          },
          "can": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Can",
            "description": "What they can do, in English sentences."
          },
          "cannot": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Cannot",
            "description": "What they cannot do, in English sentences."
          },
          "access_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Until",
            "description": "When the person's access ends."
          },
          "approver": {
            "type": "boolean",
            "title": "Approver",
            "description": "True when they may approve what others prepare."
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "name",
          "email",
          "role_title",
          "scopes",
          "areas",
          "closed_areas",
          "visibility",
          "can",
          "cannot",
          "access_until",
          "approver"
        ],
        "title": "PreviewOut"
      },
      "PriceInForce": {
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Product id."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Product code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency asked for."
          },
          "on": {
            "type": "string",
            "format": "date",
            "title": "On",
            "description": "The day asked for."
          },
          "price": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/PriceOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The list price in force: the latest from on or before the day; null when there is none in the currency."
          },
          "ssp": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SspOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The standalone selling price in force, likewise."
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "The customer asked for (its code), when one was."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Quantity",
            "description": "The quantity asked for, when a customer was (default 1)."
          },
          "customer_price": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CustomerPrice"
              },
              {
                "type": "null"
              }
            ],
            "description": "The customer's price, when the customer takes an active price list in the currency with a price of the product for the quantity on the day: the highest tier at or below the quantity, its latest from on or before the day, with the list and tier it came from. What a line proposes before the list price; null otherwise."
          }
        },
        "type": "object",
        "required": [
          "product_id",
          "code",
          "currency",
          "on",
          "price",
          "ssp"
        ],
        "title": "PriceInForce",
        "examples": [
          {
            "code": "SEAT",
            "currency": "CHF",
            "on": "2026-10-04",
            "price": {
              "created_at": "2026-10-04T08:00:00Z",
              "created_by": {
                "id": "user:alice",
                "name": "Alice",
                "type": "human"
              },
              "currency": "CHF",
              "id": "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
              "price_period": "month",
              "unit_price": "50",
              "valid_from": "2026-10-04"
            },
            "product_id": "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e"
          }
        ]
      },
      "PriceInput": {
        "properties": {
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code, e.g. `CHF`. Omitted: the entity's functional currency."
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Unit Price",
            "description": "Net list price of one unit, e.g. `50.00`."
          },
          "price_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Period",
            "description": "`month` or `year` for a recurring product (the price of one unit for that long); omitted for a one-off product (the price of one unit)."
          },
          "valid_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid From",
            "description": "The first day the price applies; omitted: today."
          }
        },
        "type": "object",
        "required": [
          "unit_price"
        ],
        "title": "PriceInput",
        "examples": [
          {
            "currency": "CHF",
            "price_period": "month",
            "unit_price": "50.00"
          },
          {
            "currency": "EUR",
            "price_period": "year",
            "unit_price": "540.00",
            "valid_from": "2027-01-01"
          }
        ]
      },
      "PriceListCustomer": {
        "properties": {
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Customer id."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Customer code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Customer name."
          }
        },
        "type": "object",
        "required": [
          "party_id",
          "code",
          "name"
        ],
        "title": "PriceListCustomer"
      },
      "PriceListInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity whose products it prices."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,39}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Unique in the entity and never changed. Omitted: made from the name (`Wholesale CHF` is `WHOLESALE-CHF`)."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What it is called."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code of all its prices; never changed. Omitted: the entity's functional currency."
          },
          "prices": {
            "items": {
              "$ref": "#/components/schemas/PriceListPriceInput"
            },
            "type": "array",
            "maxItems": 200,
            "title": "Prices",
            "description": "Prices to record with it."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name"
        ],
        "title": "PriceListInput",
        "examples": [
          {
            "code": "WHOLESALE-CHF",
            "currency": "CHF",
            "entity": "CH01",
            "name": "Wholesale CHF",
            "prices": [
              {
                "product": "SCANNER",
                "unit_price": "229.00"
              },
              {
                "min_quantity": "10",
                "product": "SCANNER",
                "unit_price": "209.00"
              }
            ]
          }
        ]
      },
      "PriceListOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Price list id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Code, unique in the entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Name."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of all its prices."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether lines propose its prices."
          },
          "prices": {
            "items": {
              "$ref": "#/components/schemas/PriceListPriceOut"
            },
            "type": "array",
            "title": "Prices",
            "description": "Every price, by product, tier and then the newest first."
          },
          "customers": {
            "items": {
              "$ref": "#/components/schemas/PriceListCustomer"
            },
            "type": "array",
            "title": "Customers",
            "description": "The customers that take it, by code."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "code",
          "name",
          "currency",
          "active",
          "prices",
          "customers",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "PriceListOut",
        "examples": [
          {
            "active": true,
            "code": "WHOLESALE-CHF",
            "created_at": "2026-01-01T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "customers": [
              {
                "code": "C-CH",
                "name": "Zürich Kunde AG",
                "party_id": "0a1b2c3d-4e5f-4a6b-8c7d-8e9f0a1b2c3d"
              }
            ],
            "entity": "CH01",
            "id": "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
            "name": "Wholesale CHF",
            "prices": [
              {
                "created_at": "2026-01-01T08:00:00Z",
                "created_by": {
                  "id": "user:alice",
                  "name": "Alice",
                  "type": "human"
                },
                "id": "9f2a3b4c-5d6e-4f7a-8b8c-9d0e1f2a3b4c",
                "min_quantity": "1",
                "product": "SCANNER",
                "product_id": "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e",
                "unit_price": "229",
                "valid_from": "2026-01-01"
              }
            ]
          }
        ]
      },
      "PriceListPriceInput": {
        "properties": {
          "product": {
            "type": "string",
            "title": "Product",
            "description": "Code (or id) of a product of the list's entity."
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Unit Price",
            "description": "Net price of one unit, e.g. `229.00`."
          },
          "price_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Period",
            "description": "`month` or `year` for a recurring product (the price of one unit for that long); omitted for a one-off product (the price of one unit)."
          },
          "min_quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Min Quantity",
            "description": "The tier: the price holds for a line of at least this quantity; default 1.",
            "default": "1"
          },
          "valid_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid From",
            "description": "The first day the price applies; omitted: today."
          }
        },
        "type": "object",
        "required": [
          "product",
          "unit_price"
        ],
        "title": "PriceListPriceInput",
        "examples": [
          {
            "product": "SCANNER",
            "unit_price": "229.00",
            "valid_from": "2026-01-01"
          },
          {
            "min_quantity": "10",
            "product": "SCANNER",
            "unit_price": "209.00",
            "valid_from": "2026-01-01"
          }
        ]
      },
      "PriceListPriceOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Price id."
          },
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Product id."
          },
          "product": {
            "type": "string",
            "title": "Product",
            "description": "Product code."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net price of one unit."
          },
          "price_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Period",
            "description": "Per `month` or `year`, or per unit."
          },
          "min_quantity": {
            "type": "string",
            "title": "Min Quantity",
            "description": "The smallest quantity the price holds for."
          },
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day it applies."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "product_id",
          "product",
          "unit_price",
          "price_period",
          "min_quantity",
          "valid_from",
          "created_by",
          "created_at"
        ],
        "title": "PriceListPriceOut"
      },
      "PriceListUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New name."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "`false`: no line proposes its prices and no customer is newly given it; `true`: it is used again."
          }
        },
        "type": "object",
        "title": "PriceListUpdate",
        "examples": [
          {
            "name": "Wholesale CHF 2027"
          },
          {
            "active": false
          }
        ]
      },
      "PriceOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Price id."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net list price of one unit."
          },
          "price_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Period",
            "description": "Per `month` or `year`, or per unit."
          },
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day it applies."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "currency",
          "unit_price",
          "price_period",
          "valid_from",
          "created_by",
          "created_at"
        ],
        "title": "PriceOut"
      },
      "Problem": {
        "properties": {
          "section": {
            "type": "string",
            "title": "Section",
            "description": "What could not be read, for example `slo:erp-api`."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why, in a few words (the API's status code or `request failed`); never a response body."
          }
        },
        "type": "object",
        "required": [
          "section",
          "reason"
        ],
        "title": "Problem"
      },
      "ProductInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity that sells it."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,39}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Leave it out and the product gets the company's next number (`P-00001`, counted without gaps); give one (e.g. `SEAT`, an article number of yours) to keep it. Unique in the entity and never changed."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What it is called on invoices."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "More detail."
          },
          "kind": {
            "type": "string",
            "enum": [
              "one_off",
              "recurring"
            ],
            "title": "Kind",
            "description": "`recurring` (priced per month or year, e.g. a seat) or `one_off` (priced per unit, e.g. a day of onboarding). Never changed."
          },
          "unit": {
            "type": "string",
            "maxLength": 40,
            "minLength": 1,
            "title": "Unit",
            "description": "What one is: `seat`, `licence`, `day`, `piece`, ...; default `unit`.",
            "default": "unit"
          },
          "revenue_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revenue Account",
            "description": "Revenue account (code or id) of the entity its lines are booked to; omitted: the entity's revenue from goods for `goods` where its chart has one, else its default revenue account."
          },
          "supply_type": {
            "type": "string",
            "enum": [
              "electronic_services",
              "goods",
              "services"
            ],
            "title": "Supply Type",
            "description": "`goods`, `services` (default) or `electronic_services`, for its lines' VAT.",
            "default": "services"
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "exempt",
              "parking",
              "reduced",
              "special",
              "standard",
              "super_reduced",
              "zero"
            ],
            "title": "Rate Type",
            "description": "The VAT rate type of its lines; default `standard`.",
            "default": "standard"
          },
          "prices": {
            "items": {
              "$ref": "#/components/schemas/PriceInput"
            },
            "type": "array",
            "maxItems": 50,
            "title": "Prices",
            "description": "List prices to record with it."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name",
          "kind"
        ],
        "title": "ProductInput",
        "examples": [
          {
            "code": "SEAT",
            "entity": "CH01",
            "kind": "recurring",
            "name": "Platform seat",
            "prices": [
              {
                "currency": "CHF",
                "price_period": "month",
                "unit_price": "50.00"
              }
            ],
            "revenue_account": "3400",
            "supply_type": "electronic_services",
            "unit": "seat"
          },
          {
            "code": "ONBOARD",
            "entity": "CH01",
            "kind": "one_off",
            "name": "Onboarding",
            "unit": "day"
          }
        ]
      },
      "ProductOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Product id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Code, unique in the entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Name."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "More detail."
          },
          "kind": {
            "type": "string",
            "enum": [
              "one_off",
              "recurring"
            ],
            "title": "Kind",
            "description": "`recurring` or `one_off`."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "What one is."
          },
          "revenue_account": {
            "type": "string",
            "title": "Revenue Account",
            "description": "Code of the revenue account."
          },
          "revenue_account_id": {
            "type": "string",
            "format": "uuid",
            "title": "Revenue Account Id",
            "description": "Id of the revenue account."
          },
          "supply_type": {
            "type": "string",
            "title": "Supply Type",
            "description": "Supply type of its lines."
          },
          "rate_type": {
            "type": "string",
            "title": "Rate Type",
            "description": "VAT rate type of its lines."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether new lines may name it."
          },
          "prices": {
            "items": {
              "$ref": "#/components/schemas/PriceOut"
            },
            "type": "array",
            "title": "Prices",
            "description": "Every list price, by currency and then the newest first."
          },
          "ssps": {
            "items": {
              "$ref": "#/components/schemas/SspOut"
            },
            "type": "array",
            "title": "Ssps",
            "description": "Every standalone selling price, by currency and then the newest first."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "code",
          "name",
          "description",
          "kind",
          "unit",
          "revenue_account",
          "revenue_account_id",
          "supply_type",
          "rate_type",
          "active",
          "prices",
          "ssps",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "ProductOut",
        "examples": [
          {
            "active": true,
            "code": "SEAT",
            "created_at": "2026-10-04T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "entity": "CH01",
            "id": "5b8c9d0e-1f2a-4b3c-8d4e-5f6a7b8c9d0e",
            "kind": "recurring",
            "name": "Platform seat",
            "prices": [
              {
                "created_at": "2026-10-04T08:00:00Z",
                "created_by": {
                  "id": "user:alice",
                  "name": "Alice",
                  "type": "human"
                },
                "currency": "CHF",
                "id": "7d0e1f2a-3b4c-4d5e-8f6a-7b8c9d0e1f2a",
                "price_period": "month",
                "unit_price": "50",
                "valid_from": "2026-10-04"
              }
            ],
            "rate_type": "standard",
            "revenue_account": "3400",
            "revenue_account_id": "6c9d0e1f-2a3b-4c4d-9e5f-6a7b8c9d0e1f",
            "ssps": [],
            "supply_type": "electronic_services",
            "unit": "seat"
          }
        ]
      },
      "ProductUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New name."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "`\"\"` clears."
          },
          "unit": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit",
            "description": "New unit."
          },
          "revenue_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revenue Account",
            "description": "New revenue account (code or id) for new lines."
          },
          "supply_type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "electronic_services",
                  "goods",
                  "services"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Supply Type",
            "description": "New supply type."
          },
          "rate_type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "exempt",
                  "parking",
                  "reduced",
                  "special",
                  "standard",
                  "super_reduced",
                  "zero"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Type",
            "description": "New VAT rate type."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "`false`: no new line names it; `true`: it is sold again."
          }
        },
        "type": "object",
        "title": "ProductUpdate",
        "examples": [
          {
            "name": "Platform seat (Pro)"
          },
          {
            "active": false
          }
        ]
      },
      "ProfitAndLoss": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency all amounts are in: the entity's functional currency, or the one asked for with `currency`."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range (ISO 8601)."
          },
          "revenue": {
            "type": "string",
            "title": "Revenue",
            "description": "Total revenue of the range."
          },
          "expenses": {
            "type": "string",
            "title": "Expenses",
            "description": "Total expenses of the range."
          },
          "net_income": {
            "type": "string",
            "title": "Net Income",
            "description": "Revenue minus expenses; negative is a loss."
          },
          "sections": {
            "items": {
              "$ref": "#/components/schemas/Section"
            },
            "type": "array",
            "title": "Sections",
            "description": "The accounts grouped by report line, in report-line order."
          },
          "translation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportTranslation"
              },
              {
                "type": "null"
              }
            ],
            "description": "Shown in another currency than the entity's own: how it was translated and the rates used; null in the entity's own currency."
          },
          "comparative": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ProfitAndLossComparative"
              },
              {
                "type": "null"
              }
            ],
            "description": "With `compare=prior_year`: the totals of the same range one year earlier and the changes; each account and section carries its own `comparative`."
          },
          "budget": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BudgetComparative"
              },
              {
                "type": "null"
              }
            ],
            "description": "With `budget=true`: the totals of the approved budget for the range and the variances; each account and section carries its own `budget`. Null when no approved budget covers the range (`notes` says why)."
          },
          "notes": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Notes",
            "description": "Caveats of the comparatives (`reportNote` codes), e.g. that there is no approved budget for the year or that a period is only partly in the range."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "start",
          "end",
          "revenue",
          "expenses",
          "net_income",
          "sections"
        ],
        "title": "ProfitAndLoss"
      },
      "ProfitAndLossComparative": {
        "properties": {
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the comparative range: `start` one year earlier (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the comparative range: `end` one year earlier, a month end staying a month end (29 February to 28 February and back) (ISO 8601)."
          },
          "revenue": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Total revenue against the comparative range."
          },
          "expenses": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Total expenses against the comparative range."
          },
          "net_income": {
            "$ref": "#/components/schemas/Comparative",
            "description": "Net income against the comparative range."
          }
        },
        "type": "object",
        "required": [
          "start",
          "end",
          "revenue",
          "expenses",
          "net_income"
        ],
        "title": "ProfitAndLossComparative"
      },
      "ProposalCriteria": {
        "properties": {
          "payment_date": {
            "type": "string",
            "format": "date",
            "title": "Payment Date",
            "description": "The day the payments would be booked; cash discounts are offered while it is within their period. A preview may look ahead; the run itself is dated today at the latest, and the bank pays on the execution date chosen when the payment file is sent."
          },
          "due_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Until",
            "description": "Last payment date: bills due on or before it are proposed (default the payment date)."
          },
          "take_discounts": {
            "type": "boolean",
            "title": "Take Discounts",
            "description": "Deduct cash discounts still available on the payment date, and also propose bills not yet due whose discount would expire by due_until.",
            "default": true
          },
          "vendors": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendors",
            "description": "Vendor codes (default all)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code: propose only bills in this currency; default: all."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "GL bank account code the run will pay from, as the run's `bank_account`; default: per currency. Only `bank_balances` depends on it."
          }
        },
        "type": "object",
        "required": [
          "payment_date"
        ],
        "title": "ProposalCriteria",
        "examples": [
          {
            "due_until": "2026-10-15",
            "payment_date": "2026-09-30",
            "take_discounts": true,
            "vendors": [
              "V-BM",
              "V-IT"
            ]
          }
        ]
      },
      "ProposalLine": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the bill."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Number of the bill."
          },
          "external_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "External Number",
            "description": "The vendor's invoice number."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Vendor code."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "Name of the vendor."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the bill."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Date of the bill."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date of the bill."
          },
          "cash_discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Percent",
            "description": "Cash discount percent of the bill, if any."
          },
          "cash_discount_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Discount Date",
            "description": "Last day the cash discount may be taken."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Gross total of the bill."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "Open amount of the bill before the discount."
          },
          "discount": {
            "type": "string",
            "title": "Discount",
            "description": "Cash discount taken by paying on the payment date."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount to pay: open less discount."
          },
          "reason": {
            "type": "string",
            "enum": [
              "cash_discount",
              "due",
              "overdue"
            ],
            "title": "Reason",
            "description": "Why it is proposed: `overdue` (due before the payment date), `due` (due by `due_until`) or `cash_discount` (not yet due, but the discount would expire)."
          },
          "payment_iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Iban",
            "description": "The bill's payment account or the vendor's."
          },
          "payment_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Reference",
            "description": "Structured reference printed on the bill, if any."
          },
          "warnings": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Warnings",
            "description": "Things to review before paying, e.g. a missing IBAN or a draft vendor."
          },
          "problems": {
            "items": {
              "$ref": "#/components/schemas/BlockerOut"
            },
            "type": "array",
            "title": "Problems",
            "description": "What would stop the payment going into a payment file (pain.001), by the same rule as `POST /v1/payment-exports`, e.g. `payment_cross_border` (`currency`, `country`): such a bill is paid in the bank's e-banking instead. Codes and details as the export's refusals."
          },
          "credit_available": {
            "type": "string",
            "title": "Credit Available",
            "description": "What the vendor has to its credit in the bill's currency: paid on account and not applied, and open credit notes (ADR-0045). Above zero, paying the bill in full would pay twice: apply the credit first (`POST /v1/applications`) or pay less.",
            "default": "0.00"
          },
          "preselected": {
            "type": "boolean",
            "title": "Preselected",
            "description": "Whether to pay the bill as proposed; false while the vendor has credit (`credit_available`), with a warning.",
            "default": true
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "external_number",
          "vendor",
          "vendor_name",
          "currency",
          "document_date",
          "due_date",
          "cash_discount_percent",
          "cash_discount_date",
          "total",
          "open",
          "discount",
          "amount",
          "reason",
          "payment_iban",
          "payment_reference",
          "warnings"
        ],
        "title": "ProposalLine"
      },
      "ProvisionAdmin": {
        "properties": {
          "email": {
            "type": "string",
            "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
            "title": "Email",
            "description": "The first administrator's email address. They sign in with a password whose link Google e-mails them when they are invited (when password sign-in is configured), or, for an address of the deployment's Google Workspace domains, with Google; the address is stored in lower case."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Display name; filled from Google at sign-in."
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "ProvisionAdmin"
      },
      "ProvisionEntity": {
        "properties": {
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street of the entity's address, at most 70 characters."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number of the address, at most 16 characters."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code of the address, at most 16 characters."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town of the address, at most 35 characters."
          },
          "contact_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Name",
            "description": "Seller contact (BT-41)."
          },
          "contact_phone": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Phone",
            "description": "Seller contact phone (BT-42)."
          },
          "contact_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contact Email",
            "description": "Seller contact email (BT-43)."
          },
          "electronic_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address",
            "description": "Seller electronic address (BT-34); defaults to contact_email."
          },
          "electronic_address_scheme": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Electronic Address Scheme",
            "description": "EAS code, e.g. EM (email), 9930 (German VAT id), 0204."
          },
          "template": {
            "type": "string",
            "enum": [
              "ch_sme",
              "de_sme",
              "generic"
            ],
            "title": "Template",
            "description": "The preset the entity starts from. `ch_sme`: Switzerland, CHF, monthly periods, VAT by the effective method per quarter. `de_sme`: Germany, EUR, monthly periods, VAT with the standard method per month and a monthly recapitulative statement. `generic`: no country or currency; send `country` and `functional_currency`. The chart is the standard chart of the entity's country (`GET /v1/platform/charts`: `ch_kmu` for CH and LI, `de_hgb` for DE, `fr_pcg` for FR, `it_civil_code` for IT, `es_pgc` for ES, `se_bas` for SE, `fi_kpl` for FI, `dk_standard` for DK, `no_ns4102` for NO, `ifrs_generic` where a country has none). Every value of a preset can be overridden below."
          },
          "code": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]{2,20}$",
            "title": "Code",
            "description": "Short unique code, 2 to 20 characters of A-Z, 0-9, `_` and `-`, e.g. `CH01`; it names the entity in every URL."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "title": "Name",
            "description": "Legal name of the entity."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code; default: the template's."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "ISO 3166-2 code of the state or canton, e.g. `DE-BY`; null when omitted."
          },
          "functional_currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Functional Currency",
            "description": "ISO 4217 code of the currency the books are kept in; default: the template's. Cannot be changed later."
          },
          "chart": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Chart",
            "description": "Chart template id (`GET /v1/platform/charts`); default: the standard chart of the entity's country."
          },
          "fiscal_year_start_month": {
            "type": "integer",
            "maximum": 12.0,
            "minimum": 1.0,
            "title": "Fiscal Year Start Month",
            "description": "Month the fiscal year starts, 1 to 12; default 1.",
            "default": 1
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "The entity's VAT number; null when omitted."
          },
          "fiscal_years": {
            "items": {
              "type": "integer",
              "maximum": 2100.0,
              "minimum": 2000.0
            },
            "type": "array",
            "title": "Fiscal Years",
            "description": "The fiscal years whose periods are opened at once, e.g. `[2026]`, each 2000 to 2100; default: the one that holds today where the company is, on its `fiscal_year_start_month`."
          },
          "fiscal_calendar": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/FiscalCalendar"
              },
              {
                "type": "null"
              }
            ],
            "description": "How to divide those years into periods; default: monthly."
          },
          "vat": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VatSettingsInput"
              },
              {
                "type": "null"
              }
            ],
            "description": "VAT settings of the entity (method, period); default: the template's. `generic` has none, so the country's defaults apply until they are saved."
          }
        },
        "type": "object",
        "required": [
          "template",
          "code",
          "name"
        ],
        "title": "ProvisionEntity",
        "examples": [
          {
            "code": "CH01",
            "fiscal_years": [
              2026
            ],
            "name": "Muster Treuhand AG",
            "template": "ch_sme",
            "vat_number": "CHE-123.456.788 MWST"
          }
        ]
      },
      "ProvisionInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "The organization's name, 1 to 200 characters."
          },
          "admin": {
            "$ref": "#/components/schemas/ProvisionAdmin",
            "description": "The first administrator, who is invited with every scope and signs in with a password or Google. The organization has no API key: it creates its own, bound to this person, after the first sign-in."
          },
          "users": {
            "items": {
              "$ref": "#/components/schemas/ProvisionUser"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Users",
            "description": "Further people to invite, up to 20. Invite a `controller` here: new vendors and the people's work need a second person (four eyes), so the administrator cannot complete the onboarding alone."
          },
          "entities": {
            "items": {
              "$ref": "#/components/schemas/ProvisionEntity"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Entities",
            "description": "The legal entities to create, each from a template. Default: none, and the first administrator sets the organization up at their first sign-in (`POST /v1/setup`): the country, accounting standard, currency, fiscal year and tax, then Production and its Test environment are made (ADR-0041)."
          }
        },
        "type": "object",
        "required": [
          "name",
          "admin"
        ],
        "title": "ProvisionInput",
        "examples": [
          {
            "admin": {
              "email": "petra.muster@example.com",
              "name": "Petra Muster"
            },
            "entities": [
              {
                "code": "CH01",
                "fiscal_years": [
                  2026
                ],
                "name": "Muster Treuhand AG",
                "template": "ch_sme",
                "vat_number": "CHE-123.456.788 MWST"
              }
            ],
            "name": "Muster Treuhand AG",
            "users": [
              {
                "email": "hans.keller@example.com",
                "name": "Hans Keller"
              }
            ]
          }
        ]
      },
      "ProvisionUser": {
        "properties": {
          "email": {
            "type": "string",
            "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
            "title": "Email",
            "description": "The first administrator's email address. They sign in with a password whose link Google e-mails them when they are invited (when password sign-in is configured), or, for an address of the deployment's Google Workspace domains, with Google; the address is stored in lower case."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Display name; filled from Google at sign-in."
          },
          "role": {
            "type": "string",
            "enum": [
              "accountant",
              "admin",
              "auditor",
              "controller",
              "viewer"
            ],
            "title": "Role",
            "description": "Preset scopes of the user: `viewer`, `accountant`, `controller` (the second person who approves what the administrator creates) or `admin`.",
            "default": "controller"
          }
        },
        "type": "object",
        "required": [
          "email"
        ],
        "title": "ProvisionUser"
      },
      "Provisioned": {
        "properties": {
          "organization": {
            "$ref": "#/components/schemas/TenantOut",
            "description": "The new organization, active."
          },
          "entities": {
            "items": {
              "$ref": "#/components/schemas/ProvisionedEntity"
            },
            "type": "array",
            "title": "Entities",
            "description": "Its entities, with their charts."
          },
          "users": {
            "items": {
              "$ref": "#/components/schemas/ProvisionedUser"
            },
            "type": "array",
            "title": "Users",
            "description": "The people invited, the administrator first. Google e-mails each of them the link that sets their password (`password_email_sent`), except people of the deployment's Google Workspace domains, who sign in with Google."
          },
          "replayed": {
            "type": "boolean",
            "title": "Replayed",
            "description": "True when this is the stored answer of an earlier request with the same `Idempotency-Key`: nothing was created now.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "organization",
          "entities",
          "users"
        ],
        "title": "Provisioned"
      },
      "ProvisionedEntity": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The entity's code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Legal name."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "ISO 4217 code of the books' currency."
          },
          "chart": {
            "type": "string",
            "title": "Chart",
            "description": "The chart template its accounts were copied from."
          },
          "role_accounts": {
            "type": "integer",
            "title": "Role Accounts",
            "description": "Number of accounts with a role: every role the services need is covered."
          },
          "fiscal_years": {
            "items": {
              "type": "integer"
            },
            "type": "array",
            "title": "Fiscal Years",
            "description": "The fiscal years whose periods were opened."
          },
          "vat_method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Method",
            "description": "The VAT method saved for the entity; null when the country's default applies."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "country",
          "functional_currency",
          "chart",
          "role_accounts",
          "fiscal_years",
          "vat_method"
        ],
        "title": "ProvisionedEntity"
      },
      "ProvisionedUser": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the user."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The sign-in address, lower case."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The scopes the user holds."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`invited` until the person has signed in."
          },
          "password_email_sent": {
            "type": "boolean",
            "title": "Password Email Sent",
            "description": "True when Google e-mailed the person the link that sets their password (false when password sign-in is not configured, or for an address of a Google Workspace domain, whose people sign in with Google).",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "id",
          "email",
          "scopes",
          "status"
        ],
        "title": "ProvisionedUser"
      },
      "QrBill": {
        "properties": {
          "iban": {
            "type": "string",
            "title": "Iban",
            "description": "IBAN or QR-IBAN of the creditor (CH or LI)."
          },
          "creditor": {
            "$ref": "#/components/schemas/Address",
            "description": "The creditor: the registered account holder's name and address."
          },
          "amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "None leaves the amount open."
          },
          "currency": {
            "type": "string",
            "enum": [
              "CHF",
              "EUR"
            ],
            "title": "Currency",
            "description": "`CHF` or `EUR`, the currency of the invoice."
          },
          "debtor": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ],
            "description": "The customer's address, when the customer has a postal code and town."
          },
          "reference_type": {
            "type": "string",
            "enum": [
              "NON",
              "QRR",
              "SCOR"
            ],
            "title": "Reference Type",
            "description": "`QRR` (QR reference, with a QR-IBAN) or `SCOR` (ISO 11649 creditor reference, with an IBAN)."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The structured reference, derived from the invoice number."
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "Unstructured message (Ustrd)."
          },
          "billing_information": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Billing Information",
            "description": "StrdBkgInf."
          },
          "alternative_procedures": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Alternative Procedures",
            "description": "Alternative payment procedures printed on the bill, if any."
          }
        },
        "type": "object",
        "required": [
          "iban",
          "creditor",
          "currency",
          "reference_type"
        ],
        "title": "QrBill"
      },
      "QrBillOut": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the sales invoice."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Number of the invoice."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Code of the GL bank account paid into."
          },
          "open_amount": {
            "type": "string",
            "title": "Open Amount",
            "description": "The open amount of the invoice that the bill asks for."
          },
          "payload": {
            "type": "string",
            "title": "Payload",
            "description": "Swiss QR Code data (CR+LF separated)."
          },
          "bill": {
            "$ref": "#/components/schemas/QrBill",
            "description": "The QR-bill fields: creditor account and address, amount, currency, debtor, reference type (`QRR` QR reference, `SCOR` creditor reference) and reference, message."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "account",
          "open_amount",
          "payload",
          "bill"
        ],
        "title": "QrBillOut"
      },
      "QuestionOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The question's id (to answer it)."
          },
          "outcome": {
            "type": "string",
            "title": "Outcome",
            "description": "The outcome it belongs to, e.g. `bank_matched`."
          },
          "item_ref": {
            "type": "string",
            "title": "Item Ref",
            "description": "The item it is about (a bank line's id, ...)."
          },
          "item_title": {
            "type": "string",
            "title": "Item Title",
            "description": "The item, as a person reads it."
          },
          "question": {
            "type": "string",
            "title": "Question",
            "description": "What the AI asks, in the outcome's language."
          },
          "status": {
            "type": "string",
            "enum": [
              "answered",
              "dropped",
              "open"
            ],
            "title": "Status",
            "description": "`open` until a person answers; `dropped` when the item was settled otherwise."
          },
          "answer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Answer",
            "description": "The person's answer."
          },
          "answered_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Answered By",
            "description": "Who answered."
          },
          "answered_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Answered At",
            "description": "When."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was asked."
          },
          "pass_id": {
            "type": "string",
            "format": "uuid",
            "title": "Pass Id",
            "description": "The pass that asked it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "outcome",
          "item_ref",
          "item_title",
          "question",
          "status",
          "answer",
          "answered_by",
          "answered_at",
          "created_at",
          "pass_id"
        ],
        "title": "QuestionOut"
      },
      "QueueInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company (entity)."
          },
          "code": {
            "type": "string",
            "pattern": "^[A-Z0-9][A-Z0-9_-]{0,19}$",
            "title": "Code",
            "description": "Its code, e.g. `SUPPORT`; never changes."
          },
          "name": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Name",
            "description": "Its name."
          },
          "inbound_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inbound Address",
            "description": "The address customers write to (the shared inbox): e-mail to it becomes cases of this queue, and replies sent from here ask to be answered to it. One queue per address in the organization."
          },
          "sla": {
            "additionalProperties": {
              "$ref": "#/components/schemas/SlaTarget"
            },
            "propertyNames": {
              "enum": [
                "high",
                "low",
                "normal",
                "urgent"
              ]
            },
            "type": "object",
            "title": "Sla",
            "description": "The service levels by priority (`urgent`, `high`, `normal`, `low`): the working minutes to the first reply and to the resolution. A priority left out has no target."
          },
          "business_hours": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BusinessHours"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the clock runs; none: around the clock."
          },
          "auto_assign": {
            "type": "boolean",
            "title": "Auto Assign",
            "description": "A new case without a person goes to the member with the fewest open cases.",
            "default": false
          },
          "members": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "maxItems": 200,
            "title": "Members",
            "description": "The people who work it (`GET /v1/people`)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "code",
          "name"
        ],
        "title": "QueueInput",
        "examples": [
          {
            "auto_assign": true,
            "business_hours": {
              "days": [
                1,
                2,
                3,
                4,
                5
              ],
              "end": "17:00",
              "start": "08:00"
            },
            "code": "SUPPORT",
            "entity": "CH01",
            "inbound_address": "support@example.ch",
            "members": [],
            "name": "Customer support",
            "sla": {
              "normal": {
                "first_response_minutes": 480,
                "resolution_minutes": 2700
              },
              "urgent": {
                "first_response_minutes": 60,
                "resolution_minutes": 480
              }
            }
          }
        ]
      },
      "QueueOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The queue's id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Its code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          },
          "inbound_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inbound Address",
            "description": "The shared inbox address; none: no inbox."
          },
          "sla": {
            "additionalProperties": {
              "$ref": "#/components/schemas/SlaTarget"
            },
            "propertyNames": {
              "enum": [
                "high",
                "low",
                "normal",
                "urgent"
              ]
            },
            "type": "object",
            "title": "Sla",
            "description": "The service levels by priority (`urgent`, `high`, `normal`, `low`): the working minutes to the first reply and to the resolution. A priority left out has no target."
          },
          "business_hours": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BusinessHours"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the clock runs; none: around the clock."
          },
          "time_zone": {
            "type": "string",
            "title": "Time Zone",
            "description": "The company's time zone, in which the hours run."
          },
          "auto_assign": {
            "type": "boolean",
            "title": "Auto Assign",
            "description": "New cases go to the member with the fewest open."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "false: no new case goes to it."
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/Person"
            },
            "type": "array",
            "title": "Members",
            "description": "The people who work it."
          },
          "open_cases": {
            "type": "integer",
            "title": "Open Cases",
            "description": "Its cases open or waiting on the customer."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who set it up (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who changed it last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "code",
          "name",
          "inbound_address",
          "sla",
          "business_hours",
          "time_zone",
          "auto_assign",
          "active",
          "members",
          "open_cases",
          "created_by",
          "created_at",
          "updated_by",
          "updated_at"
        ],
        "title": "QueueOut"
      },
      "QueueUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Its name."
          },
          "inbound_address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inbound Address",
            "description": "The shared inbox address; `\"\"` removes it."
          },
          "sla": {
            "anyOf": [
              {
                "additionalProperties": {
                  "$ref": "#/components/schemas/SlaTarget"
                },
                "propertyNames": {
                  "enum": [
                    "high",
                    "low",
                    "normal",
                    "urgent"
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sla",
            "description": "The service levels by priority (`urgent`, `high`, `normal`, `low`): the working minutes to the first reply and to the resolution. A priority left out has no target. Replaces the whole set."
          },
          "business_hours": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/BusinessHours"
              },
              {
                "type": "null"
              }
            ],
            "description": "When the clock runs; null: around the clock."
          },
          "auto_assign": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auto Assign",
            "description": "Assign new cases automatically."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "false: no new case goes to it; the cases in it stay."
          },
          "members": {
            "anyOf": [
              {
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "type": "array",
                "maxItems": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Members",
            "description": "The people who work it; replaces the list."
          }
        },
        "type": "object",
        "title": "QueueUpdate",
        "examples": [
          {
            "auto_assign": true,
            "sla": {
              "urgent": {
                "first_response_minutes": 30,
                "resolution_minutes": 240
              }
            }
          }
        ]
      },
      "QuotaInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity; quotas are in its currency."
          },
          "quotas": {
            "items": {
              "$ref": "#/components/schemas/QuotaLine"
            },
            "type": "array",
            "maxItems": 600,
            "minItems": 1,
            "title": "Quotas",
            "description": "Each person's quota for a month."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "quotas"
        ],
        "title": "QuotaInput",
        "examples": [
          {
            "entity": "CH01",
            "quotas": [
              {
                "amount": "50000.00",
                "month": "2026-10",
                "user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
              },
              {
                "amount": "50000.00",
                "month": "2026-11",
                "user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
              }
            ]
          }
        ]
      },
      "QuotaLine": {
        "properties": {
          "user_id": {
            "type": "string",
            "format": "uuid",
            "title": "User Id",
            "description": "The person (`GET /v1/people`)."
          },
          "month": {
            "type": "string",
            "pattern": "^\\d{4}-(0[1-9]|1[0-2])$",
            "title": "Month",
            "description": "`YYYY-MM`."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "What they are to win in the month; 0 takes it back."
          }
        },
        "type": "object",
        "required": [
          "user_id",
          "month",
          "amount"
        ],
        "title": "QuotaLine"
      },
      "QuotaOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "person": {
            "$ref": "#/components/schemas/Person",
            "description": "Whose quota."
          },
          "month": {
            "type": "string",
            "title": "Month",
            "description": "`YYYY-MM`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The quota."
          },
          "updated_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Updated By",
            "description": "Who set it last (actor object)."
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "person",
          "month",
          "currency",
          "amount",
          "updated_by",
          "updated_at"
        ],
        "title": "QuotaOut",
        "examples": [
          {
            "amount": "50000.00",
            "currency": "CHF",
            "entity": "CH01",
            "month": "2026-10",
            "person": {
              "email": "lena@example.com",
              "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "name": "Lena Meier"
            },
            "updated_at": "2026-10-01T08:00:00Z",
            "updated_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            }
          }
        ]
      },
      "QuoteAnswerOut": {
        "properties": {
          "revision": {
            "type": "integer",
            "title": "Revision",
            "description": "The version answered."
          },
          "decision": {
            "type": "string",
            "enum": [
              "accepted",
              "declined"
            ],
            "title": "Decision",
            "description": "`accepted` or `declined`."
          },
          "signer_name": {
            "type": "string",
            "title": "Signer Name",
            "description": "The name the customer's person gave."
          },
          "signer_email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Signer Email",
            "description": "The address they gave; null if none."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why they declined, if they said."
          },
          "link_prefix": {
            "type": "string",
            "title": "Link Prefix",
            "description": "The link it was given on."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the PDF of the version answered."
          },
          "client_address": {
            "type": "string",
            "title": "Client Address",
            "description": "The internet address it came from."
          },
          "user_agent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "User Agent",
            "description": "The browser, as it named itself."
          },
          "answered_at": {
            "type": "string",
            "format": "date-time",
            "title": "Answered At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "revision",
          "decision",
          "signer_name",
          "signer_email",
          "reason",
          "link_prefix",
          "sha256",
          "client_address",
          "user_agent",
          "answered_at"
        ],
        "title": "QuoteAnswerOut"
      },
      "QuoteLinkInput": {
        "properties": {
          "handed_to": {
            "type": "string",
            "maxLength": 320,
            "minLength": 1,
            "title": "Handed To",
            "description": "To whom you give the link, for the record."
          }
        },
        "type": "object",
        "required": [
          "handed_to"
        ],
        "title": "QuoteLinkInput",
        "examples": [
          {
            "handed_to": "Anna Muster"
          }
        ]
      },
      "QuoteLinkIssued": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the link."
          },
          "prefix": {
            "type": "string",
            "title": "Prefix",
            "description": "The link's public part, shown in the customer's answer."
          },
          "handed_to": {
            "type": "string",
            "title": "Handed To",
            "description": "To whom it was given."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "first_viewed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Viewed At",
            "description": "When the customer first opened it."
          },
          "last_viewed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Viewed At",
            "description": "When the customer last opened it."
          },
          "revoked_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revoked At",
            "description": "When it was turned off; null if it works."
          },
          "token": {
            "type": "string",
            "title": "Token",
            "description": "The link's secret, shown this once: the customer's page is `/app/quote/{token}`. Only its hash is kept."
          }
        },
        "type": "object",
        "required": [
          "id",
          "prefix",
          "handed_to",
          "created_by",
          "created_at",
          "first_viewed_at",
          "last_viewed_at",
          "revoked_at",
          "token"
        ],
        "title": "QuoteLinkIssued"
      },
      "QuoteLinkOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the link."
          },
          "prefix": {
            "type": "string",
            "title": "Prefix",
            "description": "The link's public part, shown in the customer's answer."
          },
          "handed_to": {
            "type": "string",
            "title": "Handed To",
            "description": "To whom it was given."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "first_viewed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Viewed At",
            "description": "When the customer first opened it."
          },
          "last_viewed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Viewed At",
            "description": "When the customer last opened it."
          },
          "revoked_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revoked At",
            "description": "When it was turned off; null if it works."
          }
        },
        "type": "object",
        "required": [
          "id",
          "prefix",
          "handed_to",
          "created_by",
          "created_at",
          "first_viewed_at",
          "last_viewed_at",
          "revoked_at"
        ],
        "title": "QuoteLinkOut"
      },
      "QuoteNight": {
        "properties": {
          "night": {
            "type": "string",
            "format": "date",
            "title": "Night",
            "description": "The night (the evening it starts)."
          },
          "price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Price",
            "description": "Net price of one room; null: no price is known."
          },
          "season": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Season",
            "description": "The season that prices it; null: the list price."
          },
          "free": {
            "type": "integer",
            "title": "Free",
            "description": "Rooms of the type still free that night."
          }
        },
        "type": "object",
        "required": [
          "night",
          "price",
          "season",
          "free"
        ],
        "title": "QuoteNight"
      },
      "QuoteOnlineCard": {
        "properties": {
          "revision": {
            "type": "integer",
            "title": "Revision",
            "description": "The current version."
          },
          "revisions": {
            "items": {
              "$ref": "#/components/schemas/QuoteRevisionOut"
            },
            "type": "array",
            "title": "Revisions",
            "description": "Versions handed over, the first first."
          },
          "links": {
            "items": {
              "$ref": "#/components/schemas/QuoteLinkOut"
            },
            "type": "array",
            "title": "Links",
            "description": "Links given to the customer, oldest first."
          },
          "answer": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QuoteAnswerOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The customer's answer online; null if none."
          }
        },
        "type": "object",
        "required": [
          "revision",
          "revisions",
          "links",
          "answer"
        ],
        "title": "QuoteOnlineCard",
        "description": "Of a quote: its version, the versions handed over, its links and the online answer."
      },
      "QuoteOnlineView": {
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "accepted",
              "declined",
              "expired",
              "open",
              "revising",
              "withdrawn"
            ],
            "title": "State",
            "description": "`open` (it can be answered), `expired`, `revising` (the seller is changing it: a new version follows), `accepted`, `declined` or `withdrawn`."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of the texts."
          },
          "test_copy": {
            "type": "boolean",
            "title": "Test Copy",
            "description": "From a test copy: not a real offer."
          },
          "seller_name": {
            "type": "string",
            "title": "Seller Name",
            "description": "Who makes the offer."
          },
          "seller_lines": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Seller Lines",
            "description": "The seller's address and contact."
          },
          "seller_logo": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Seller Logo",
            "description": "The seller's logo as a `data:image/png;base64,` address; null: none."
          },
          "seller_colour": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Seller Colour",
            "description": "The seller's brand colour, `#rrggbb`; null: the default."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "To whom."
          },
          "buyer_lines": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Buyer Lines",
            "description": "The customer's address as printed."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "The quote's number."
          },
          "revision": {
            "type": "integer",
            "title": "Revision",
            "description": "Its version."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Its day."
          },
          "valid_until": {
            "type": "string",
            "format": "date",
            "title": "Valid Until",
            "description": "The last day to accept it."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's own reference."
          },
          "payment_terms_days": {
            "type": "integer",
            "title": "Payment Terms Days",
            "description": "Days to pay the invoices of the order."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/OnlineLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines; empty while it is being changed."
          },
          "vat": {
            "items": {
              "$ref": "#/components/schemas/OnlineVat"
            },
            "type": "array",
            "title": "Vat",
            "description": "VAT by rate."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "Document discount in percent."
          },
          "discount_amount": {
            "type": "string",
            "title": "Discount Amount",
            "description": "Document discount in money."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Net total."
          },
          "tax_total": {
            "type": "string",
            "title": "Tax Total",
            "description": "VAT."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total including VAT."
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "Notes and the VAT remarks the lines need."
          },
          "answered_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Answered By",
            "description": "Who answered online; null if not online."
          },
          "answered_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Answered At",
            "description": "When it was accepted or declined."
          }
        },
        "type": "object",
        "required": [
          "state",
          "language",
          "test_copy",
          "seller_name",
          "seller_lines",
          "customer_name",
          "buyer_lines",
          "number",
          "revision",
          "document_date",
          "valid_until",
          "currency",
          "customer_reference",
          "payment_terms_days",
          "lines",
          "vat",
          "discount_percent",
          "discount_amount",
          "net_total",
          "tax_total",
          "total",
          "notes",
          "answered_by",
          "answered_at"
        ],
        "title": "QuoteOnlineView",
        "description": "The quote as its customer sees it on the link."
      },
      "QuoteOut": {
        "properties": {
          "room_type": {
            "type": "string",
            "title": "Room Type",
            "description": "Product code of the room type."
          },
          "customer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer",
            "description": "Customer code whose prices are used."
          },
          "arrival": {
            "type": "string",
            "format": "date",
            "title": "Arrival",
            "description": "Arrival day."
          },
          "departure": {
            "type": "string",
            "format": "date",
            "title": "Departure",
            "description": "Departure day."
          },
          "rooms": {
            "type": "integer",
            "title": "Rooms",
            "description": "Rooms asked for."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code of the prices."
          },
          "nights": {
            "items": {
              "$ref": "#/components/schemas/QuoteNight"
            },
            "type": "array",
            "title": "Nights",
            "description": "Each night from arrival to departure."
          },
          "total": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Total",
            "description": "Net total of the stay (each night's price times the rooms); null when a night has no price."
          },
          "available": {
            "type": "boolean",
            "title": "Available",
            "description": "Whether every night has the rooms free."
          }
        },
        "type": "object",
        "required": [
          "room_type",
          "customer",
          "arrival",
          "departure",
          "rooms",
          "currency",
          "nights",
          "total",
          "available"
        ],
        "title": "QuoteOut"
      },
      "QuoteRevisionOut": {
        "properties": {
          "revision": {
            "type": "integer",
            "title": "Revision",
            "description": "The version, from 1."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "The quote's day in that version."
          },
          "valid_until": {
            "type": "string",
            "format": "date",
            "title": "Valid Until",
            "description": "The last day to accept that version."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Net total, after discounts."
          },
          "tax_total": {
            "type": "string",
            "title": "Tax Total",
            "description": "VAT."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total including VAT."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the PDF the customer got."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who handed it over first."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was first handed over (UTC)."
          }
        },
        "type": "object",
        "required": [
          "revision",
          "document_date",
          "valid_until",
          "currency",
          "net_total",
          "tax_total",
          "total",
          "sha256",
          "created_by",
          "created_at"
        ],
        "title": "QuoteRevisionOut"
      },
      "RateUse": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "average",
              "closing",
              "historical",
              "transaction"
            ],
            "title": "Kind",
            "description": "`closing` (the last fixing of the month of the date), `average` (the mean of the month's fixings), `historical` (the rate of the date a subsidiary is consolidated from) or `transaction` (the rate of the date of an equity movement)."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The entity whose currency it translates."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "The functional currency."
          },
          "quote": {
            "type": "string",
            "title": "Quote",
            "description": "The reporting currency: the rate is units of it per unit of `base`."
          },
          "period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period",
            "description": "The calendar month `YYYY-MM` of a closing or average rate."
          },
          "date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Date",
            "description": "The date of a historical or transaction rate."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "The rate used."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "The rate source: the ECB euro foreign exchange reference rates."
          },
          "first_fixing": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "First Fixing",
            "description": "The first fixing the rate rests on."
          },
          "last_fixing": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Fixing",
            "description": "The last fixing the rate rests on."
          },
          "fixings": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fixings",
            "description": "How many fixings an average is the mean of."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The data-vNext dataset version that served the rate, so the run can be checked against the same pinned data."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "entity",
          "base",
          "quote",
          "period",
          "date",
          "rate",
          "source",
          "first_fixing",
          "last_fixing",
          "fixings",
          "dataset_version"
        ],
        "title": "RateUse"
      },
      "Reason": {
        "properties": {
          "words": {
            "type": "string",
            "title": "Words",
            "description": "The vocabulary of the code, such as `consolidation.exception`: the screens word it as `<words>.<code>`."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "What it is, by a stable code."
          },
          "details": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Details",
            "description": "The values the words name (amounts as decimal strings, days as ISO dates, lists, or further reasons); null for an older record kept without them."
          },
          "text": {
            "type": "string",
            "title": "Text",
            "description": "The same in English words."
          }
        },
        "type": "object",
        "required": [
          "words",
          "code",
          "details",
          "text"
        ],
        "title": "Reason"
      },
      "ReceiptInput": {
        "properties": {
          "receipt_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Receipt Date",
            "description": "Date the goods or services arrived (ISO 8601); default today where the company is."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Free text, e.g. the delivery note number (up to 500 characters)."
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "Code or id of the warehouse the stock items come into (or go back from); default the entity's default warehouse. Lines that are no stock items ignore it."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ReceiptLineInput"
            },
            "type": "array",
            "maxItems": 500,
            "minItems": 1,
            "title": "Lines",
            "description": "What was received per order line, 1 to 500 lines."
          }
        },
        "type": "object",
        "required": [
          "lines"
        ],
        "title": "ReceiptInput",
        "examples": [
          {
            "lines": [
              {
                "line_no": 1,
                "quantity": "6"
              }
            ],
            "note": "Delivery note 4711",
            "receipt_date": "2026-09-08"
          }
        ]
      },
      "ReceiptLineInput": {
        "properties": {
          "line_no": {
            "type": "integer",
            "minimum": 1.0,
            "title": "Line No",
            "description": "The order line."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Quantity",
            "description": "Received; negative corrects an earlier receipt (at most 6 decimals)."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "quantity"
        ],
        "title": "ReceiptLineInput"
      },
      "ReceiptLineOut": {
        "properties": {
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Number of the order line."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description of the order line."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity received (negative for a correction)."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "description",
          "quantity"
        ],
        "title": "ReceiptLineOut"
      },
      "ReceiptOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the receipt."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Receipt number."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`; `pending_approval` while its posting waits for a second person (not counted by the 3-way match yet); `rejected` when the second person rejected it: it no longer counts as received."
          },
          "receipt_date": {
            "type": "string",
            "format": "date",
            "title": "Receipt Date",
            "description": "Date the goods or services arrived."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Free text, e.g. the delivery note number; null when none."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it (`type`, `id`, `name`)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was recorded (UTC)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ReceiptLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "What was received per order line."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status",
          "receipt_date",
          "note",
          "created_by",
          "created_at",
          "lines"
        ],
        "title": "ReceiptOut"
      },
      "ReceiptPreviewLine": {
        "properties": {
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Number of the order line."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Description of the order line."
          },
          "item": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Item",
            "description": "Code of the stock item the line buys; null for none."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity received (negative: sent back)."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "What the receipt posts for the line in the functional currency: the receipt value (negative: the value the goods sent back take out). Zero when it posts nothing."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "The account debited (the stock item's inventory account, or the order line's account); null when the line posts nothing."
          },
          "posts": {
            "type": "boolean",
            "title": "Posts",
            "description": "False for a line that needs no receipt, or names no account (it posts nothing)."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "description",
          "item",
          "quantity",
          "value",
          "account",
          "posts"
        ],
        "title": "ReceiptPreviewLine"
      },
      "ReceiptPreviewOut": {
        "properties": {
          "order_id": {
            "type": "string",
            "format": "uuid",
            "title": "Order Id",
            "description": "Id of the purchase order."
          },
          "order_number": {
            "type": "string",
            "title": "Order Number",
            "description": "Number of the purchase order."
          },
          "receipt_date": {
            "type": "string",
            "format": "date",
            "title": "Receipt Date",
            "description": "The day of the receipt."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency of the entity."
          },
          "order_currency": {
            "type": "string",
            "title": "Order Currency",
            "description": "Currency of the order."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "Exchange rate of the receipt day: functional currency per unit of the order's currency (1 in the same currency)."
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "The warehouse the stock items come into; null when no line is a stock item."
          },
          "grni_account": {
            "type": "string",
            "title": "Grni Account",
            "description": "The GR/IR account credited (debited when sent back)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ReceiptPreviewLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "Per receipt line."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total value the receipt posts."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "order_number",
          "receipt_date",
          "currency",
          "order_currency",
          "rate",
          "warehouse",
          "grni_account",
          "lines",
          "total"
        ],
        "title": "ReceiptPreviewOut"
      },
      "RecentEntry": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Id (uuid) of the entry, as text."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "The entry number."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "The posting date (ISO 8601)."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the entry is for."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "`manual` or the subledger that created it."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Total debits in the functional currency."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "entry_date",
          "description",
          "source",
          "amount"
        ],
        "title": "RecentEntry"
      },
      "RecognitionItem": {
        "properties": {
          "contract": {
            "type": "string",
            "title": "Contract",
            "description": "Number of the revenue contract, e.g. `RC-2026-000001`."
          },
          "contract_id": {
            "type": "string",
            "format": "uuid",
            "title": "Contract Id",
            "description": "Id of the revenue contract."
          },
          "obligation_id": {
            "type": "string",
            "format": "uuid",
            "title": "Obligation Id",
            "description": "Id of the performance obligation."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Position of the obligation in its contract, from 1."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the obligation promises."
          },
          "revenue_account": {
            "type": "string",
            "title": "Revenue Account",
            "description": "Code of the revenue account credited."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The contract's currency, which `amount` is in."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Revenue recognised, in the contract's currency."
          },
          "functional_amount": {
            "type": "string",
            "title": "Functional Amount",
            "description": "The same revenue in the entity's functional currency, as booked: for a contract in another currency, what billing in advance covered at the rate it was billed at, the rest at the rate of the period end (ADR-0050)."
          },
          "billed_part": {
            "type": "string",
            "title": "Billed Part",
            "description": "Of `amount`, the part billing in advance covered (booked at the rate the contract liability is carried at); the rest was recognised before it was billed. Equals `amount` for a contract in the functional currency."
          },
          "lines": {
            "type": "integer",
            "title": "Lines",
            "description": "Schedule lines recognised."
          },
          "catch_up": {
            "type": "integer",
            "title": "Catch Up",
            "description": "Of those, lines due before the period began (recognised in this period)."
          }
        },
        "type": "object",
        "required": [
          "contract",
          "contract_id",
          "obligation_id",
          "line_no",
          "description",
          "revenue_account",
          "currency",
          "amount",
          "functional_amount",
          "billed_part",
          "lines",
          "catch_up"
        ],
        "title": "RecognitionItem"
      },
      "RecognitionRunOut": {
        "properties": {
          "run_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Run Id",
            "description": "Id of the recorded run; null for a preview or when nothing was due."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`, e.g. `2026-09`."
          },
          "recognised": {
            "items": {
              "$ref": "#/components/schemas/RecognitionItem"
            },
            "type": "array",
            "title": "Recognised",
            "description": "Revenue recognised per obligation: the schedule lines due by the period end (time lines of the months through it, satisfied point-in-time obligations)."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Revenue recognised, in the functional currency."
          },
          "exchange_differences": {
            "items": {
              "$ref": "#/components/schemas/ExchangeDifferenceItem"
            },
            "type": "array",
            "title": "Exchange Differences",
            "description": "Realised exchange differences of contracts in a foreign currency, posted with the recognition entry (ADR-0050)."
          },
          "remeasured": {
            "items": {
              "$ref": "#/components/schemas/RemeasurementItem"
            },
            "type": "array",
            "title": "Remeasured",
            "description": "Unbilled receivables in a foreign currency remeasured at the closing rate (monetary items, IAS 21.23), posted with the presentation entry (ADR-0050)."
          },
          "presentation": {
            "items": {
              "$ref": "#/components/schemas/PresentationItem"
            },
            "type": "array",
            "title": "Presentation",
            "description": "The contracts whose presentation changes: each one's debit position at the period end and the change posted (reversed on the first day of the next period)."
          },
          "recognition": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The recognition entry (Dr contract liability / Cr revenue, and any exchange difference) with the approval policy decision; null when nothing was due."
          },
          "presentation_entry": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The presentation entry (Dr contract asset or unbilled receivable / Cr contract liability, auto-reversing); null when no presentation changes, or when the recognition entry waits for approval (run again once it is decided)."
          },
          "waiting": {
            "items": {
              "$ref": "#/components/schemas/WaitingItem"
            },
            "type": "array",
            "title": "Waiting",
            "description": "Contracts in a foreign currency left for a later run because the ECB rate of the period end is not published yet (a run before the period's last day): their lines due stay due and their unbilled receivable is not remeasured; everything else is recognised as usual (ADR-0050)."
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "What the run left for later or to see to first, in English words."
          },
          "note_reasons": {
            "items": {
              "$ref": "#/components/schemas/Reason"
            },
            "type": "array",
            "title": "Note Reasons",
            "description": "`notes` by code, in the same order (`erp.contracts.words.RECOGNITION_NOTES`): the screens word each as `periodClose.recognitionNote.<code>` from its `details`."
          },
          "completed": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Completed",
            "description": "The contracts the run completed: their last day is before today and on or before the period end, and every schedule line in force is recognised by a posted entry."
          },
          "recognised_through": {
            "type": "string",
            "format": "date",
            "title": "Recognised Through",
            "description": "The last day whose revenue the run recognises: the period end once it has passed, else yesterday (revenue is recognised only once it is earned)."
          },
          "left_for_later": {
            "type": "integer",
            "title": "Left For Later",
            "description": "Schedule lines of the period whose day has not passed yet: left for a run after it (a run of the current period before its last day).",
            "default": 0
          }
        },
        "type": "object",
        "required": [
          "run_id",
          "period",
          "recognised",
          "total",
          "presentation",
          "recognition",
          "presentation_entry",
          "recognised_through"
        ],
        "title": "RecognitionRunOut"
      },
      "ReconcileAccount": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "GL account code, e.g. `1020`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name in the user's language."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency the account holds."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "currency"
        ],
        "title": "ReconcileAccount"
      },
      "ReconcileInput": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "GL bank account code, e.g. `1020`."
          },
          "on": {
            "type": "string",
            "format": "date",
            "title": "On",
            "description": "The statement date reconciled."
          },
          "statement_balance": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Statement Balance",
            "description": "The closing balance on the bank's statement, needed only when no imported statement for the date carries one (a CSV file)."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why the account is reconciled although part of the difference is unexplained; required then."
          }
        },
        "type": "object",
        "required": [
          "account",
          "on"
        ],
        "title": "ReconcileInput",
        "examples": [
          {
            "account": "1020",
            "on": "2026-09-30"
          }
        ]
      },
      "ReconcileRequest": {
        "properties": {
          "apply": {
            "type": "boolean",
            "title": "Apply",
            "description": "Submit valid proposals for approval.",
            "default": true
          },
          "min_confidence": {
            "type": "number",
            "maximum": 1.0,
            "minimum": 0.0,
            "title": "Min Confidence",
            "description": "Proposals the model is less sure of than this (0 to 1) are returned as `proposed` and not applied; default 0.6.",
            "default": 0.6
          },
          "limit": {
            "type": "integer",
            "maximum": 40.0,
            "minimum": 1.0,
            "title": "Limit",
            "description": "How many unmatched bank lines to review, oldest first, 1 to 40; default 25.",
            "default": 25
          }
        },
        "type": "object",
        "title": "ReconcileRequest",
        "examples": [
          {
            "apply": true,
            "limit": 20,
            "min_confidence": 0.7
          }
        ]
      },
      "ReconcileResult": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "reviewed": {
            "type": "integer",
            "title": "Reviewed",
            "description": "How many unmatched bank lines were reviewed."
          },
          "outcomes": {
            "items": {
              "$ref": "#/components/schemas/Outcome"
            },
            "type": "array",
            "title": "Outcomes",
            "description": "One outcome per reviewed line."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "reviewed",
          "outcomes"
        ],
        "title": "ReconcileResult"
      },
      "Reconciliation": {
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day the open items are read as of."
          },
          "relationships": {
            "items": {
              "$ref": "#/components/schemas/RelationshipReconciliation"
            },
            "type": "array",
            "title": "Relationships",
            "description": "One entry per relationship."
          }
        },
        "type": "object",
        "required": [
          "as_of",
          "relationships"
        ],
        "title": "Reconciliation",
        "examples": [
          {
            "as_of": "2026-09-30",
            "relationships": [
              {
                "carrying": [
                  {
                    "balance": "10000.00",
                    "entity": "CH01",
                    "functional_currency": "CHF"
                  },
                  {
                    "balance": "0.00",
                    "entity": "DE01",
                    "functional_currency": "EUR"
                  }
                ],
                "currencies": [
                  {
                    "a_net": "10000.00",
                    "a_payable": "0.00",
                    "a_receivable": "10000.00",
                    "b_net": "0.00",
                    "b_payable": "0.00",
                    "b_receivable": "0.00",
                    "currency": "CHF",
                    "difference": "10000.00"
                  }
                ],
                "detail": "1 item differs, all timing: the counterpart books its part",
                "difference_in_tolerance_currency": "10000.00",
                "entity_a": "CH01",
                "entity_b": "DE01",
                "items": [
                  {
                    "counter": {
                      "document_date": "2026-09-21",
                      "document_id": "7c2d6a0e-2a64-4d36-b0a3-9e5a1d6f2c02",
                      "entity": "DE01",
                      "kind": "purchase_bill",
                      "party_code": "IC-CH01",
                      "status": "draft",
                      "total": "10000.00"
                    },
                    "counter_open": "0.00",
                    "currency": "CHF",
                    "difference": "10000.00",
                    "explained": true,
                    "link_id": "e3a1f0b2-6d7c-4b8a-9c0d-1e2f3a4b5c03",
                    "origin": {
                      "document_date": "2026-09-21",
                      "document_id": "0b9b8a53-1c4e-4f3a-8f55-3f2c3b8a6d01",
                      "entity": "CH01",
                      "kind": "sales_invoice",
                      "number": "INV-2026-000001",
                      "party_code": "IC-DE01",
                      "status": "posted",
                      "total": "10000.00"
                    },
                    "origin_open": "10000.00",
                    "reason": "mirror_draft"
                  }
                ],
                "relationship_id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
                "status": "warn",
                "tolerance_amount": "1.00",
                "tolerance_currency": "CHF",
                "unexplained_in_tolerance_currency": "0.00"
              }
            ]
          }
        ]
      },
      "ReconciliationDone": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the record."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "The bank account reconciled, e.g. `1020`."
          },
          "statement_date": {
            "type": "string",
            "format": "date",
            "title": "Statement Date",
            "description": "The statement date reconciled, ISO 8601."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency the account holds."
          },
          "statement_balance": {
            "type": "string",
            "title": "Statement Balance",
            "description": "The bank's closing balance on the date."
          },
          "ledger_balance": {
            "type": "string",
            "title": "Ledger Balance",
            "description": "The account's posted balance on the date."
          },
          "bank_items_total": {
            "type": "string",
            "title": "Bank Items Total",
            "description": "Statement lines up to the date not in the ledger then."
          },
          "ledger_items_total": {
            "type": "string",
            "title": "Ledger Items Total",
            "description": "Posted entries up to the date no statement line showed then."
          },
          "unexplained": {
            "type": "string",
            "title": "Unexplained",
            "description": "What the items did not explain; zero mostly."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why it was marked reconciled with an unexplained rest."
          },
          "done_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Done By",
            "description": "Who marked it done (`name`, `type`, `id`)."
          },
          "done_at": {
            "type": "string",
            "format": "date-time",
            "title": "Done At",
            "description": "When it was marked reconciled, ISO 8601."
          },
          "reset_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reset Reason",
            "description": "Why the record was reset; null while it stands."
          },
          "reset_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reset By",
            "description": "Who reset it (`name`, `type`, `id`); null while it stands."
          },
          "reset_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reset At",
            "description": "When it was reset, ISO 8601; null while it stands. A reset record no longer counts: the date can be reconciled again."
          }
        },
        "type": "object",
        "required": [
          "id",
          "account",
          "statement_date",
          "currency",
          "statement_balance",
          "ledger_balance",
          "bank_items_total",
          "ledger_items_total",
          "unexplained",
          "note",
          "done_by",
          "done_at"
        ],
        "title": "ReconciliationDone"
      },
      "ReconcilingItem": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "`outside_scope_sales` (revenue of lines outside the scope of VAT: interest and fees for late payment, supplies within a VAT group or an Organschaft), `outside_scope_purchases` (the same on bills), `foreign_vat_purchases` (foreign VAT that vendors charged under their own country's law, which cannot be reclaimed and is booked as cost, with the net amount of purchases taxed abroad), `non_deductible_vat_purchases` (the part of input VAT the law does not let the company deduct, booked as cost: `vat_recovery_percent` of a bill line), `fx_rounding` (the FX rounding of invoices and bills in a foreign currency), or `other_period_sales` and `other_period_purchases` (turnover booked in this period whose VAT is due in another because of its date of supply or, under the cash basis, its payment, less the reverse)."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "What it is, in words."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "In the functional currency: revenue (sales) or expense (purchases) that no VAT turnover contains, positive as the item's name reads (a credit note or a cash discount makes it smaller). `fx_rounding` is the net expense of the rounding: positive when the rounding cost (a debit), negative when it gained (a credit)."
          }
        },
        "type": "object",
        "required": [
          "code",
          "label",
          "amount"
        ],
        "title": "ReconcilingItem",
        "description": "An amount that explains a difference between the ledger and what the VAT report or the\nreturn takes: it is in the ledger and in no VAT turnover."
      },
      "RecordsOut": {
        "properties": {
          "dataset": {
            "type": "string",
            "title": "Dataset",
            "description": "Name of the dataset."
          },
          "records": {
            "type": "integer",
            "title": "Records",
            "description": "Number of records in it."
          },
          "series": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Series",
            "description": "Number of series (e.g. currencies) in it; null if not a series dataset."
          }
        },
        "type": "object",
        "required": [
          "dataset",
          "records"
        ],
        "title": "RecordsOut"
      },
      "RecoveryInput": {
        "properties": {
          "write_off_id": {
            "type": "string",
            "format": "uuid",
            "title": "Write Off Id",
            "description": "The posted write-off of the invoice the money is for."
          },
          "recovery_date": {
            "type": "string",
            "format": "date",
            "title": "Recovery Date",
            "description": "The day the money arrived (ISO 8601): on or after the write-off, not after today, in an open period."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "What was received, VAT included, in the invoice's currency; at most what is written off and not received yet."
          },
          "bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Bank Account",
            "description": "Code of the bank account the money arrived on; default: the main bank account for the invoice's currency."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Free text, e.g. where the money came from."
          }
        },
        "type": "object",
        "required": [
          "write_off_id",
          "recovery_date",
          "amount"
        ],
        "title": "RecoveryInput",
        "examples": [
          {
            "amount": "200.00",
            "bank_account": "1020",
            "note": "First dividend from the bankruptcy office.",
            "recovery_date": "2026-11-20",
            "write_off_id": "0f6b6a3e-5d7c-4b8e-9a51-2f4c1d0e7a90"
          }
        ]
      },
      "RecurringActivation": {
        "properties": {
          "template": {
            "$ref": "#/components/schemas/RecurringInvoiceOut",
            "description": "The template after the request."
          },
          "policy": {
            "type": "string",
            "title": "Policy",
            "description": "`allow` (it is active now, or runs again with the terms already approved) or `require_approval` (a second person decides: `approval_id`)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request when a second person must decide; else null."
          }
        },
        "type": "object",
        "required": [
          "template",
          "policy",
          "approval_id"
        ],
        "title": "RecurringActivation",
        "examples": [
          {
            "approval_id": "c2d4e6f8-0a1b-4c3d-9e5f-7a8b9c0d1e2f",
            "policy": "require_approval",
            "template": {
              "approval_id": "c2d4e6f8-0a1b-4c3d-9e5f-7a8b9c0d1e2f",
              "auto_submit": false,
              "created_at": "2026-10-27T16:03:10Z",
              "created_by": {
                "id": "user:alice",
                "name": "Alice",
                "type": "human"
              },
              "currency": "CHF",
              "entity": "CH01",
              "frequency": "monthly",
              "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
              "invoices_made": 1,
              "lines": [
                {
                  "description": "Hosting and support",
                  "quantity": "1",
                  "rate_type": "standard",
                  "reverse_charge": false,
                  "supply_type": "services",
                  "unit_price": "450.00",
                  "vat_scope": "in_scope"
                }
              ],
              "name": "Hosting and support, monthly",
              "net_total": "450.00",
              "next_due": "2026-12-01",
              "party_code": "C-CH",
              "party_id": "7d1e2f3a-4b5c-4d6e-8f70-91a2b3c4d5e6",
              "party_name": "Zürich Kunde AG",
              "payment_terms_days": 30,
              "start_date": "2026-11-01",
              "status": "pending_approval",
              "terms_approved": false
            }
          }
        ]
      },
      "RecurringInvoiceInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity that issues the invoices."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Code (or id) of the customer the invoices are for."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What the template is called in lists, e.g. `Hosting and support, monthly`. It is not printed on the invoices."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Frequency",
            "description": "`monthly`, `quarterly` (every 3 months) or `yearly`. The due dates are counted from `start_date` and keep its day of the month; a month that is too short takes its last day (start on the 31st: 31 Jan, 28 Feb, 31 Mar, 30 Apr)."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first due date (ISO 8601): the date of the first invoice. It may lie in the past; a run then makes the invoices that are due, a year of monthly ones at most per run."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "The last day an invoice may fall due, inclusive (ISO 8601); null for no end. After the last due date the template ends by itself."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency of the invoices; default: the customer's currency."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Days from the invoice date to its due date; default: the customer's own payment terms."
          },
          "auto_submit": {
            "type": "boolean",
            "title": "Auto Submit",
            "description": "`false` (default): each due invoice is created as a draft for a person to submit. `true`: the system submits it through the approval policy as it is made; the approval of the terms says so on its face.",
            "default": false
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text printed on every invoice (the invoice's `notes`)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/DocumentLineInput"
            },
            "type": "array",
            "minItems": 1,
            "title": "Lines",
            "description": "The lines of every invoice, as on `POST /v1/documents`: tax is determined for each invoice on its own date by the same rules as for an invoice entered by hand."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "party",
          "name",
          "frequency",
          "start_date",
          "lines"
        ],
        "title": "RecurringInvoiceInput",
        "examples": [
          {
            "entity": "CH01",
            "frequency": "monthly",
            "lines": [
              {
                "description": "Hosting and support",
                "quantity": "1",
                "unit_price": "450.00"
              }
            ],
            "name": "Hosting and support, monthly",
            "party": "C-CH",
            "payment_terms_days": 30,
            "start_date": "2026-11-01"
          }
        ]
      },
      "RecurringInvoiceOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the template."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity that issues the invoices."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer, e.g. `C-CH`."
          },
          "party_name": {
            "type": "string",
            "title": "Party Name",
            "description": "Name of the customer."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What the template is called in lists."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "draft",
              "ended",
              "paused",
              "pending_approval"
            ],
            "title": "Status",
            "description": "`draft`, `pending_approval` (a second person is to approve the terms), `active` (runs generate invoices), `paused` or `ended` (the end date has passed)."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Frequency",
            "description": "`monthly`, `quarterly` or `yearly`."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first due date."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "The last due date, inclusive; null for none."
          },
          "next_due": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Due",
            "description": "The next due date an invoice is to be made for; null once the template has ended. It is due when it is on or before the day of the run."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the invoices."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Days from the invoice date to its due date; null: the customer's terms."
          },
          "auto_submit": {
            "type": "boolean",
            "title": "Auto Submit",
            "description": "Whether the system submits each invoice as it is made (through the approval policy) instead of leaving a draft."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text printed on every invoice."
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Net total of one invoice (the sum of the line amounts, rounded to the currency), before VAT."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/RecurringLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines of every invoice."
          },
          "terms_digest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms Digest",
            "description": "SHA-256 of the terms a second person approved; null before the first approval."
          },
          "terms_approved": {
            "type": "boolean",
            "title": "Terms Approved",
            "description": "Whether the current terms are the approved ones. False after a change to an approved template: it stays paused until the new terms are approved."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The pending approval request (`POST /v1/approvals/{approval_id}/approve`) while `status` is `pending_approval`; else null."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved the terms (`type`, `id`, `name`); null before."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When the terms were approved (UTC)."
          },
          "paused_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Paused By",
            "description": "Who paused it, or changed its terms."
          },
          "paused_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Paused At",
            "description": "When it was paused (UTC)."
          },
          "pause_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pause Reason",
            "description": "Why it was paused."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created the template."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was created (UTC)."
          },
          "invoices_made": {
            "type": "integer",
            "title": "Invoices Made",
            "description": "How many invoices its runs have made so far."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "party_id",
          "party_code",
          "party_name",
          "name",
          "status",
          "frequency",
          "start_date",
          "end_date",
          "next_due",
          "currency",
          "payment_terms_days",
          "auto_submit",
          "notes",
          "net_total",
          "lines",
          "terms_digest",
          "terms_approved",
          "approval_id",
          "approved_by",
          "approved_at",
          "paused_by",
          "paused_at",
          "pause_reason",
          "created_by",
          "created_at",
          "invoices_made"
        ],
        "title": "RecurringInvoiceOut",
        "examples": [
          {
            "approved_at": "2026-10-28T09:12:44Z",
            "approved_by": {
              "id": "user:bob",
              "name": "Bob",
              "type": "human"
            },
            "auto_submit": false,
            "created_at": "2026-10-27T16:03:10Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "entity": "CH01",
            "frequency": "monthly",
            "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "invoices_made": 1,
            "lines": [
              {
                "description": "Hosting and support",
                "quantity": "1",
                "rate_type": "standard",
                "reverse_charge": false,
                "supply_type": "services",
                "unit_price": "450.00",
                "vat_scope": "in_scope"
              }
            ],
            "name": "Hosting and support, monthly",
            "net_total": "450.00",
            "next_due": "2026-12-01",
            "party_code": "C-CH",
            "party_id": "7d1e2f3a-4b5c-4d6e-8f70-91a2b3c4d5e6",
            "party_name": "Zürich Kunde AG",
            "payment_terms_days": 30,
            "start_date": "2026-11-01",
            "status": "active",
            "terms_approved": true,
            "terms_digest": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"
          }
        ]
      },
      "RecurringInvoiceUpdate": {
        "properties": {
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Code (or id) of the customer."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "What the template is called."
          },
          "frequency": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "monthly",
                  "quarterly",
                  "yearly"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Frequency",
            "description": "`monthly`, `quarterly` or `yearly`; before the first invoice."
          },
          "start_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start Date",
            "description": "The first due date (ISO 8601); before the first invoice."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "The last due date, inclusive; `null` removes the end."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency of the invoices."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Days to pay; `null` takes the customer's own terms."
          },
          "auto_submit": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Auto Submit",
            "description": "Whether the system submits each invoice as it is made."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text on every invoice."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/DocumentLineInput"
                },
                "type": "array",
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "The new lines; they replace all existing lines (at least one)."
          }
        },
        "type": "object",
        "title": "RecurringInvoiceUpdate",
        "description": "Changes to a template. Omitted fields keep their value; `null` clears an optional one.\n\nA change to anything but `name` is a change of the terms: it pauses an active template (and\ntakes a template waiting for approval back to draft), and the template runs again only after\na second person has approved the new terms. `frequency` and `start_date` can change only\nbefore the first invoice was made.",
        "examples": [
          {
            "end_date": "2027-10-31",
            "payment_terms_days": 14
          }
        ]
      },
      "RecurringJournalInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity whose books the entries are in."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What the recurring journal is called in lists, e.g. `Office rent accrual`."
          },
          "description": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Description",
            "description": "The description of every entry it makes, shown in the journal and the general ledger."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Frequency",
            "description": "`monthly`, `quarterly` (every 3 months) or `yearly`. The due dates are counted from `start_date` and keep its day of the month; a month that is too short takes its last day, and a start on the last day of a month stays on month ends (30 Sep, 31 Oct, 30 Nov; 31 Jan, 28 Feb, 31 Mar)."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first due date (ISO 8601): the date of the first entry. It may lie in the past, in an open period."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "The last day an entry may fall due, inclusive (ISO 8601); null for no end. After the last due date the recurring journal ends by itself."
          },
          "reverse_next_period": {
            "type": "boolean",
            "title": "Reverse Next Period",
            "description": "An accrual: each entry is reversed on the first day of the period after its own (the entry's `auto_reverse_on`), when it posts.",
            "default": false
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/RecurringJournalLineInput"
            },
            "type": "array",
            "minItems": 2,
            "title": "Lines",
            "description": "The lines of every entry, at least two. Debits and credits must balance."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name",
          "description",
          "frequency",
          "start_date",
          "lines"
        ],
        "title": "RecurringJournalInput",
        "examples": [
          {
            "description": "Accrued office rent",
            "entity": "CH01",
            "frequency": "monthly",
            "lines": [
              {
                "account": "6000",
                "debit": "4500.00",
                "description": "Office rent Zürich"
              },
              {
                "account": "2300",
                "credit": "4500.00",
                "description": "Accrued rent"
              }
            ],
            "name": "Office rent accrual",
            "reverse_next_period": true,
            "start_date": "2026-09-30"
          }
        ]
      },
      "RecurringJournalLineInput": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code (or id) in the entity, e.g. `6000`."
          },
          "debit": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Debit",
            "description": "Debit amount in the line's currency, e.g. `4500.00`; zero or omitted on a credit line. Exactly one of debit and credit must be above zero.",
            "default": "0"
          },
          "credit": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Credit",
            "description": "Credit amount; zero or omitted on a debit line.",
            "default": "0"
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency of the line; default the entity's functional currency. Each entry converts it at the rate of its own date."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text of this line; may be null."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "Analysis tags of the line, as on a journal entry, e.g. `{\"cost_centre\": \"ADMIN\"}`; empty when omitted."
          }
        },
        "type": "object",
        "required": [
          "account"
        ],
        "title": "RecurringJournalLineInput",
        "examples": [
          {
            "account": "6000",
            "debit": "4500.00",
            "description": "Office rent Zürich"
          }
        ]
      },
      "RecurringJournalLineOut": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Debit amount in the line's currency."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Credit amount in the line's currency."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Currency of the line; null: the functional one."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text of the line."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "Analysis tags of the line."
          }
        },
        "type": "object",
        "required": [
          "account",
          "debit",
          "credit",
          "currency",
          "description",
          "dimensions"
        ],
        "title": "RecurringJournalLineOut",
        "description": "A line of a recurring journal as stored."
      },
      "RecurringJournalOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the recurring journal."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What it is called in lists."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "The description of every entry it makes."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "draft",
              "ended",
              "paused"
            ],
            "title": "Status",
            "description": "`draft` (never activated, or its lines, start, frequency, end date or reversal changed since), `active` (runs make entries), `paused` or `ended` (the end date has passed)."
          },
          "frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Frequency",
            "description": "`monthly`, `quarterly` or `yearly`."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first due date."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "The last due date, inclusive; null for none."
          },
          "next_due": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Due",
            "description": "The next due date an entry is to be made for; null once it has ended."
          },
          "reverse_next_period": {
            "type": "boolean",
            "title": "Reverse Next Period",
            "description": "Whether each entry is reversed on the first day of the next period."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/RecurringJournalLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines of every entry."
          },
          "activated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Activated By",
            "description": "Who last activated it; null for a draft."
          },
          "activated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Activated At",
            "description": "When it was last activated (UTC); null for a draft."
          },
          "paused_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Paused By",
            "description": "Who paused it."
          },
          "paused_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Paused At",
            "description": "When it was paused (UTC)."
          },
          "pause_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pause Reason",
            "description": "Why it was paused."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was created (UTC)."
          },
          "entries_made": {
            "type": "integer",
            "title": "Entries Made",
            "description": "How many entries its runs have made so far (a rejected entry not counted)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "name",
          "description",
          "status",
          "frequency",
          "start_date",
          "end_date",
          "next_due",
          "reverse_next_period",
          "lines",
          "activated_by",
          "activated_at",
          "paused_by",
          "paused_at",
          "pause_reason",
          "created_by",
          "created_at",
          "entries_made"
        ],
        "title": "RecurringJournalOut",
        "examples": [
          {
            "activated_at": "2026-09-29T08:10:00Z",
            "activated_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "created_at": "2026-09-29T08:05:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "description": "Accrued office rent",
            "entity": "CH01",
            "entries_made": 1,
            "frequency": "monthly",
            "id": "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b",
            "lines": [
              {
                "account": "6000",
                "credit": "0.00",
                "debit": "4500.00",
                "description": "Office rent Zürich",
                "dimensions": {}
              },
              {
                "account": "2300",
                "credit": "4500.00",
                "debit": "0.00",
                "description": "Accrued rent",
                "dimensions": {}
              }
            ],
            "name": "Office rent accrual",
            "next_due": "2026-10-31",
            "reverse_next_period": true,
            "start_date": "2026-09-30",
            "status": "active"
          }
        ]
      },
      "RecurringJournalPause": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why; kept with it and in the audit trail."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "RecurringJournalPause",
        "examples": [
          {
            "reason": "Lease under renegotiation"
          }
        ]
      },
      "RecurringJournalRunInput": {
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "title": "Through",
            "description": "Make the entries that fall due on or before this day (ISO 8601, inclusive); never after today where the entity is."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Only the recurring journals of this entity (code or id)."
          },
          "template": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Template",
            "description": "Only this recurring journal (it must be active)."
          }
        },
        "type": "object",
        "required": [
          "through"
        ],
        "title": "RecurringJournalRunInput",
        "examples": [
          {
            "entity": "CH01",
            "through": "2026-10-31"
          }
        ]
      },
      "RecurringJournalRunItem": {
        "properties": {
          "template_id": {
            "type": "string",
            "format": "uuid",
            "title": "Template Id",
            "description": "The recurring journal the entry was made from."
          },
          "template_name": {
            "type": "string",
            "title": "Template Name",
            "description": "Its name."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "The due date of the period; also the entry date."
          },
          "status": {
            "type": "string",
            "enum": [
              "failed",
              "pending_approval",
              "posted",
              "rejected"
            ],
            "title": "Status",
            "description": "`posted`, `pending_approval` (the approval policy asked for a second person; the run record becomes `posted` or `rejected` when the entry is decided) or `failed` (nothing was made; `error` says why, the next run tries again). A rejected entry's period is due again: the next run makes it again."
          },
          "entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Id",
            "description": "The journal entry; null when it failed."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Its number once posted."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why a failed attempt failed; null otherwise."
          }
        },
        "type": "object",
        "required": [
          "template_id",
          "template_name",
          "due_date",
          "status",
          "entry_id",
          "entry_number",
          "error"
        ],
        "title": "RecurringJournalRunItem"
      },
      "RecurringJournalRunOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the run record."
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "title": "Template Id",
            "description": "The recurring journal."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "The due date of the period."
          },
          "status": {
            "type": "string",
            "enum": [
              "failed",
              "pending_approval",
              "posted",
              "rejected"
            ],
            "title": "Status",
            "description": "What came of the period; see the run result."
          },
          "entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Id",
            "description": "The journal entry; null when it failed."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Its number once posted."
          },
          "entry_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Status",
            "description": "The entry's status now (`pending_approval`, `posted`, `rejected`...)."
          },
          "reversal_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversal Id",
            "description": "The entry that reversed it (an accrual's reversal); null when none."
          },
          "reversal_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversal Number",
            "description": "The reversal's number."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why a failed attempt failed."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who ran it (`type`, `id`, `name`)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "template_id",
          "due_date",
          "status",
          "entry_id",
          "entry_number",
          "entry_status",
          "reversal_id",
          "reversal_number",
          "error",
          "created_by",
          "created_at"
        ],
        "title": "RecurringJournalRunOut",
        "examples": [
          {
            "created_at": "2026-10-01T08:30:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "due_date": "2026-09-30",
            "entry_id": "8e4f2a1b-3c5d-4e6f-9a7b-1c2d3e4f5a6b",
            "entry_number": "JE-2026-000123",
            "entry_status": "posted",
            "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
            "reversal_id": "0f1e2d3c-4b5a-4968-8776-655443322110",
            "reversal_number": "JE-2026-000124",
            "status": "posted",
            "template_id": "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b"
          }
        ]
      },
      "RecurringJournalRunResult": {
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "title": "Through",
            "description": "The day the run went through."
          },
          "made": {
            "type": "integer",
            "title": "Made",
            "description": "Entries made by this run (posted or waiting for approval)."
          },
          "failed": {
            "type": "integer",
            "title": "Failed",
            "description": "Periods that failed; they stay due."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/RecurringJournalRunItem"
            },
            "type": "array",
            "title": "Items",
            "description": "One item per period made or failed, by recurring journal and due date."
          },
          "more_due": {
            "type": "boolean",
            "title": "More Due",
            "description": "True when a recurring journal still has due dates after this run (twelve per run at most, and a run stops at a failed period): run again."
          }
        },
        "type": "object",
        "required": [
          "through",
          "made",
          "failed",
          "items",
          "more_due"
        ],
        "title": "RecurringJournalRunResult",
        "examples": [
          {
            "failed": 0,
            "items": [
              {
                "due_date": "2026-10-31",
                "entry_id": "8e4f2a1b-3c5d-4e6f-9a7b-1c2d3e4f5a6b",
                "entry_number": "JE-2026-000123",
                "status": "posted",
                "template_id": "5b1c7e2a-9d34-4f6b-a8e1-3c2d4e5f6a7b",
                "template_name": "Office rent accrual"
              }
            ],
            "made": 1,
            "more_due": false,
            "through": "2026-10-31"
          }
        ]
      },
      "RecurringJournalUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "What it is called."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "The description of the entries."
          },
          "frequency": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "monthly",
                  "quarterly",
                  "yearly"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Frequency",
            "description": "`monthly`, `quarterly` or `yearly`; before the first entry."
          },
          "start_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Start Date",
            "description": "The first due date (ISO 8601); before the first entry."
          },
          "end_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "End Date",
            "description": "The last due date, inclusive; `null` removes the end."
          },
          "reverse_next_period": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reverse Next Period",
            "description": "Whether each entry is reversed in the next period."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/RecurringJournalLineInput"
                },
                "type": "array",
                "minItems": 2
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "The new lines; they replace all existing lines."
          }
        },
        "type": "object",
        "title": "RecurringJournalUpdate",
        "description": "Changes to a recurring journal. Omitted fields keep their value; `null` removes the end\ndate. `frequency` and `start_date` can change only before the first entry was made. A change\nof `lines`, `end_date` or `reverse_next_period` returns an active or paused recurring journal\nto `draft` (its activation cleared): a person activates it again.",
        "examples": [
          {
            "end_date": "2027-12-31",
            "reverse_next_period": true
          }
        ]
      },
      "RecurringLineOut": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string",
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Text of the line, e.g. `Consulting September 2026`. Required, except on a line that names a `product` (default: the product's name) or credits a line (`credits_line`; default: that line's text)."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity as a decimal string, greater than 0; default `1`.",
            "default": "1"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price",
            "description": "Net unit price; negative only on vendor documents (e.g. a discount line). Required, except on a line that names a `product`: left out, it takes the customer's price from its price list in the document's currency, else the product's list price on the document date (`422` `product_unpriced` when it has neither); and on a credit note line with `credits_line`: left out, the line credits that line as it was, at its price and (unless the line gives its own) its discount."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "A discount on the line, in percent of quantity times unit price (at most 100; 0 for none). Give this or `discount_amount`, not both."
          },
          "discount_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Amount",
            "description": "A discount on the line, as an amount off quantity times unit price in the document currency, at most what the line is worth (0 for none). Give this or `discount_percent`."
          },
          "credits_line": {
            "anyOf": [
              {
                "type": "integer",
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Credits Line",
            "description": "Credit notes with `credits`: the number of the line of the credited document this line credits. Without a `unit_price` the line credits it as it was: it takes that line's price and its discount with its share of the document discount, in proportion to the quantity it credits (what is left of them when it credits the rest of the line), and returns them as its own `unit_price` and discount, with `as_credited` true when it gave no discount either. To change the quantity of such a line later, send it again without price and discount; sent with them, it credits them as given. With a `unit_price` only the discount the line gives applies; where the credited line had a discount (its own or a share of the document discount) the line must give one (`0` for none), else `422` `credit_discount_required`. The line also takes that line's tax decision as stored (`supply_type`, `rate_type`, `tax_category`, `vat_scope` and the `tax`: treatment, taxing jurisdiction, rates), so it reverses exactly the tax charged; one it states that differs is not taken, with the warning `credit_takes_credited_vat`."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Defaults to the product's revenue account, else the party or entity default."
          },
          "product": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product",
            "description": "Sales documents: code (or id) of an active product of the entity (`GET /v1/products`). The line takes the product's revenue account, `supply_type` and `rate_type` unless it names its own, and its name and price when it gives none (the price in force: `GET /v1/products/{product_id}/price`); the document's `provenance.filled` says what was taken."
          },
          "obligation": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Obligation",
            "description": "Sales documents: id of the performance obligation of an active revenue contract of the same customer and currency that the line bills (`GET /v1/revenue-contracts/{contract_id}`). The line is booked to the contract liability account (the role `contract_liability`), not to revenue: the recognition run makes the revenue (`POST /v1/periods/{period_id}/revenue-recognition`). It takes no `account` of its own, is not a supply of `goods`, and the net billed of the contract never exceeds its transaction price (posting is refused, `422`)."
          },
          "sales_line": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Line",
            "description": "Sales invoices: id of the sales order line the line invoices (`GET /v1/sales-documents/{document}`), of an open order of the same customer and currency. The invoices of an order line never add up to more than was ordered less what was closed (`422`); a draft reserves its quantity until it is voided. Usually set by `POST /v1/sales-documents/{document}/invoice`."
          },
          "delivery_line": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delivery Line",
            "description": "Sales invoices: id of the line of a posted delivery note of the same customer that the line invoices (`GET /v1/delivery-notes/{note_id}`), of the same product. What the invoices of a delivery note line add up to, less what credit notes took back, never exceeds what was delivered less what came back (`422`). The goods left with the delivery note, so the invoice moves no stock. Usually set by `POST /v1/delivery-notes/{note_id}/invoice`. A line of a stock item that names none ships with the invoice: posting the invoice issues the goods (Dr cost of goods sold / Cr inventory)."
          },
          "goods_returned": {
            "type": "boolean",
            "title": "Goods Returned",
            "description": "Sales credit notes: the goods of this line came back. The line names the line it credits (`credits_line`), of a stock item; posting the credit note brings the quantity back into stock at the cost it left with (Dr inventory / Cr cost of goods sold). Without it no stock moves.",
            "default": false
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "Code (or id) of the warehouse the goods come back to (`goods_returned`) or ship from with the invoice (a stock item's invoice line that names no delivery note line); default the entity's default warehouse."
          },
          "supply_type": {
            "type": "string",
            "enum": [
              "electronic_services",
              "goods",
              "services"
            ],
            "title": "Supply Type",
            "description": "`goods`, `services` (default) or `electronic_services`; part of the place-of-supply decision.",
            "default": "services"
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "exempt",
              "parking",
              "reduced",
              "special",
              "standard",
              "super_reduced",
              "zero"
            ],
            "title": "Rate Type",
            "description": "Which VAT rate of the jurisdiction applies: `standard` (default), `reduced`, `super_reduced`, `parking`, `zero`, `special` or `exempt`.",
            "default": "standard"
          },
          "tax_category": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Category",
            "description": "One of the categories of the rate (`GET /v1/entities/{entity}/vat-rate-types`), e.g. `books`: it chooses the rate where the rate type has several (France reduced: 5.5 % or 10 %) and names the kind of an exempt supply (`insurance`). Omit for none."
          },
          "printed_tax_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Printed Tax Amount",
            "description": "VAT shown on a vendor bill; compared with the determined VAT."
          },
          "vat_recovery_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Recovery Percent",
            "description": "Purchase bills and their credit notes: how much of the line's input VAT the company may deduct, in percent (0 to 100, two places), e.g. `0` for a gift whose VAT the law excludes or `50` for a car used half privately. The rest is booked as part of the cost on the line's own account, not as input VAT, so no VAT return reports it. Omit (null) to take the account's `vat_recovery_percent`, else 100. A self-assessed line still owes all of its VAT. Below 100 it is refused (422) on a line without input VAT of our own: a sales line, one outside VAT, foreign VAT booked as cost, US sales or use tax, a Canadian line of several taxes."
          },
          "reverse_charge": {
            "type": "boolean",
            "title": "Reverse Charge",
            "description": "Vendor documents: the vendor invoices under reverse charge (EN 16931 VAT category AE, e.g. UStG §13b), so the VAT is self-assessed at the determined rate.",
            "default": false
          },
          "use_tax": {
            "type": "boolean",
            "title": "Use Tax",
            "description": "A US company's bill line the vendor charged no sales tax on, for something used in the company's own state: the company self-assesses use tax on it at the state's rate and its use tax area's (ADR-0064). Refused on sales documents and for companies outside the US.",
            "default": false
          },
          "vat_scope": {
            "type": "string",
            "enum": [
              "in_scope",
              "outside"
            ],
            "title": "Vat Scope",
            "description": "`in_scope` (default): the tax is determined as usual. `outside`: the line is outside the scope of VAT, like interest and fees for late payment (compensation for damage), a supply within a VAT group or an Organschaft. It needs `vat_scope_reason`, has no tax determination and rate 0, carries no tax tag (so no VAT report or return has it) and prints the remark of its reason in the document's language. It takes no `tax_category`, `printed_tax_amount` or `reverse_charge`, and a document with such a line carries no cash discount.",
            "default": "in_scope"
          },
          "vat_scope_reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "damages",
                  "organschaft",
                  "vat_group"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Scope Reason",
            "description": "Required with `vat_scope` `outside`, refused otherwise: `damages` (compensation for damage), `vat_group` (a supply within a Swiss VAT group, Art. 13 MWSTG) or `organschaft` (an Innenumsatz of a German Organschaft, § 2 para. 2 no. 2 UStG)."
          },
          "dimensions": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Dimensions",
            "description": "Dimension code to value code, e.g. `{\"cost_centre\": \"CC-200\", \"project\": \"P-17\"}` (`GET /v1/dimensions`): each an active value, valid on the document date in its company. They go onto the journal lines of the line's amount (not its VAT or the receivable or payable). An account may require a dimension (`required_accounts` of the dimension): the document is then refused at submission without it."
          },
          "until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Until",
            "description": "The last due date the line is invoiced on: the last day of the revenue contract it bills, after that contract was ended early or shortened; null for every due date."
          }
        },
        "type": "object",
        "title": "RecurringLineOut",
        "description": "A line of a recurring invoice as stored: the fields of an invoice line as entered. It is\na model of its own so that `DocumentLineInput`, an input everywhere else, is not an output."
      },
      "RecurringPause": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why; kept with the template and in the audit."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "RecurringPause",
        "examples": [
          {
            "reason": "Price list under renegotiation: hold invoices"
          }
        ]
      },
      "RecurringRevenueReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The report's currency: the entity's functional currency."
          },
          "from_month": {
            "type": "string",
            "title": "From Month",
            "description": "The first month, `YYYY-MM`."
          },
          "to_month": {
            "type": "string",
            "title": "To Month",
            "description": "The last month, `YYYY-MM` (the current month by default)."
          },
          "today": {
            "type": "string",
            "format": "date",
            "title": "Today",
            "description": "Today where the entity is."
          },
          "unconverted": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unconverted",
            "description": "Currencies without an ECB rate on a month's day, left out of the converted amounts of that month."
          },
          "months": {
            "items": {
              "$ref": "#/components/schemas/MrrMonth"
            },
            "type": "array",
            "title": "Months",
            "description": "Each month, oldest first."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "from_month",
          "to_month",
          "today",
          "unconverted",
          "months"
        ],
        "title": "RecurringRevenueReport",
        "examples": [
          {
            "currency": "CHF",
            "entity": "CH01",
            "from_month": "2026-10",
            "months": [
              {
                "arr": {
                  "amount": "140424.00",
                  "by_currency": [
                    {
                      "amount": "90000.00",
                      "currency": "CHF"
                    },
                    {
                      "amount": "54360.00",
                      "currency": "EUR"
                    }
                  ]
                },
                "as_of": "2026-10-23",
                "churn": {
                  "amount": "-1000.00",
                  "by_currency": [
                    {
                      "amount": "-1000.00",
                      "currency": "CHF"
                    }
                  ]
                },
                "churned_customers": 1,
                "closing": {
                  "amount": "11702.00",
                  "by_currency": [
                    {
                      "amount": "7500.00",
                      "currency": "CHF"
                    },
                    {
                      "amount": "4530.00",
                      "currency": "EUR"
                    }
                  ]
                },
                "contraction": {
                  "amount": "0.00",
                  "by_currency": []
                },
                "currency_effect": "-12.00",
                "customer_churn_rate": "8.3",
                "customers": 12,
                "customers_opening": 12,
                "expansion": {
                  "amount": "214.00",
                  "by_currency": [
                    {
                      "amount": "230.00",
                      "currency": "EUR"
                    }
                  ]
                },
                "fixing_date": "2026-10-23",
                "month": "2026-10",
                "movements": [
                  {
                    "amount": "-1000.00",
                    "converted": "-1000.00",
                    "currency": "CHF",
                    "kind": "churn",
                    "party_code": "C-1002",
                    "party_id": "0b9c2f4e-3d1a-4c55-9a77-6f1e2d3c4b5a",
                    "party_name": "Alpen Logistik AG",
                    "subscriptions": [
                      {
                        "id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
                        "number": "SUB-000004"
                      }
                    ]
                  }
                ],
                "mrr_churn_rate": "8.4",
                "net_mrr_retention": "93.4",
                "new": {
                  "amount": "500.00",
                  "by_currency": [
                    {
                      "amount": "500.00",
                      "currency": "CHF"
                    }
                  ]
                },
                "new_customers": 1,
                "opening": {
                  "amount": "12000.00",
                  "by_currency": [
                    {
                      "amount": "8000.00",
                      "currency": "CHF"
                    },
                    {
                      "amount": "4300.00",
                      "currency": "EUR"
                    }
                  ]
                },
                "reactivated_customers": 0,
                "reactivation": {
                  "amount": "0.00",
                  "by_currency": []
                }
              }
            ],
            "to_month": "2026-10",
            "today": "2026-10-23",
            "unconverted": []
          }
        ]
      },
      "RecurringRunInput": {
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "title": "Through",
            "description": "Make the invoices that fall due on or before this day (ISO 8601, inclusive). It may not lie more than a day after the server's date (UTC), so your own date is always accepted."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Only the templates of this entity (code or id); default: all."
          },
          "template": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Template",
            "description": "Only this template (it must be active); default: every one."
          }
        },
        "type": "object",
        "required": [
          "through"
        ],
        "title": "RecurringRunInput",
        "examples": [
          {
            "entity": "CH01",
            "through": "2026-11-30"
          }
        ]
      },
      "RecurringRunItem": {
        "properties": {
          "template_id": {
            "type": "string",
            "format": "uuid",
            "title": "Template Id",
            "description": "The template the invoice was made from."
          },
          "template_name": {
            "type": "string",
            "title": "Template Name",
            "description": "Its name."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "The due date of the period; also the invoice date."
          },
          "status": {
            "type": "string",
            "enum": [
              "drafted",
              "failed",
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "`drafted` (left for a person to submit), `posted`, `pending_approval` (the approval policy asked for a second person) or `failed` (nothing was made; `error` says why, and the next run tries again)."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The invoice; null when it failed."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Its number once posted; null for a draft or a failure."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why a failed attempt failed; null otherwise."
          }
        },
        "type": "object",
        "required": [
          "template_id",
          "template_name",
          "due_date",
          "status",
          "document_id",
          "document_number",
          "error"
        ],
        "title": "RecurringRunItem"
      },
      "RecurringRunOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the run record."
          },
          "template_id": {
            "type": "string",
            "format": "uuid",
            "title": "Template Id",
            "description": "The template."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "The due date of the period."
          },
          "status": {
            "type": "string",
            "enum": [
              "drafted",
              "failed",
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "What came of the period; see the run result."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The invoice; null when it failed."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Its number once posted."
          },
          "document_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Status",
            "description": "The invoice's status now (`draft`, `pending_approval`, `posted`, `void`...)."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why a failed attempt failed."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who ran it (`type`, `id`, `name`)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "template_id",
          "due_date",
          "status",
          "document_id",
          "document_number",
          "document_status",
          "error",
          "created_by",
          "created_at"
        ],
        "title": "RecurringRunOut",
        "examples": [
          {
            "created_at": "2026-11-02T08:30:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "document_id": "9b2f6a3e-1c4d-4e8a-8f10-5d7c2a9e4b11",
            "document_number": "INV-2026-000042",
            "document_status": "posted",
            "due_date": "2026-11-01",
            "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
            "status": "posted",
            "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        ]
      },
      "RecurringRunResult": {
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "title": "Through",
            "description": "The day the run went through."
          },
          "made": {
            "type": "integer",
            "title": "Made",
            "description": "Invoices made by this run (drafts and posted ones)."
          },
          "failed": {
            "type": "integer",
            "title": "Failed",
            "description": "Periods that failed; they stay due."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/RecurringRunItem"
            },
            "type": "array",
            "title": "Items",
            "description": "One entry per period made or failed, by template and due date."
          },
          "more_due": {
            "type": "boolean",
            "title": "More Due",
            "description": "True when a template still has due dates after this run (a run makes twelve per template at most, and stops at a failed period): run again."
          }
        },
        "type": "object",
        "required": [
          "through",
          "made",
          "failed",
          "items",
          "more_due"
        ],
        "title": "RecurringRunResult",
        "examples": [
          {
            "failed": 0,
            "items": [
              {
                "document_id": "9b2f6a3e-1c4d-4e8a-8f10-5d7c2a9e4b11",
                "due_date": "2026-11-01",
                "status": "drafted",
                "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "template_name": "Hosting and support, monthly"
              },
              {
                "document_id": "0f1e2d3c-4b5a-4968-8776-655443322110",
                "due_date": "2026-12-01",
                "status": "drafted",
                "template_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "template_name": "Hosting and support, monthly"
              }
            ],
            "made": 2,
            "more_due": false,
            "through": "2026-12-01"
          }
        ]
      },
      "RegisterCheck": {
        "properties": {
          "country": {
            "type": "string",
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country the number was checked for."
          },
          "vat_number": {
            "type": "string",
            "title": "Vat Number",
            "description": "The number as it was sent to the register, compacted."
          },
          "registry": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "ch_uid",
                  "uk_hmrc",
                  "vies"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Registry",
            "description": "`vies` (EU VIES, also XI for Northern Ireland), `ch_uid` (Swiss UID register) or `uk_hmrc` (HMRC's VAT number check); null when the country has none here."
          },
          "status": {
            "type": "string",
            "enum": [
              "invalid",
              "no_register",
              "not_configured",
              "unavailable",
              "valid"
            ],
            "title": "Status",
            "description": "`valid` (the register knows the number as registered for VAT), `invalid` (it does not), `unavailable` (the register did not answer: try again later), `not_configured` (this server has no access to the register yet, e.g. HMRC without its credentials: the number was not checked) or `no_register` (no register is checked for this country)."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The registered name, when the register gives one."
          },
          "address": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Address",
            "description": "The registered address on one line, when the register gives one."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street, when the register splits it."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Building number, if given."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code, if given."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town, if given."
          },
          "name_matches": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name Matches",
            "description": "Whether the registered name matches `name` of the request (case, punctuation and legal-form suffixes ignored); null when either is missing."
          },
          "message": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "Why the number is invalid or the register unavailable."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The register's reference for this consultation, kept as proof that the number was checked: HMRC's consultation number, given when the check names your own UK VAT number as the one asking (a customer or vendor card's check does)."
          },
          "checked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Checked At",
            "description": "When the register answered (UTC)."
          },
          "cached": {
            "type": "boolean",
            "title": "Cached",
            "description": "`true` when the answer came from the last day's cache.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "country",
          "vat_number",
          "registry",
          "status",
          "checked_at"
        ],
        "title": "RegisterCheck",
        "description": "What the public register says about a VAT number. Advisory: nothing is refused on it."
      },
      "RegisterCheckInput": {
        "properties": {
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country of the party, e.g. `DE`. A number shaped like another country's (e.g. an `IE` registration of a US company, `ATU…` at a German address) is checked in that country's register. Omitted: the country the number's prefix names (`no_register` for a number without one); the answer says which.",
            "examples": [
              "DE"
            ]
          },
          "vat_number": {
            "type": "string",
            "maxLength": 40,
            "minLength": 4,
            "title": "Vat Number",
            "description": "The VAT number as written, e.g. `DE811569869` or `CHE-123.456.788 MWST`.",
            "examples": [
              "DE811569869"
            ]
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "The party's name as you have it: `name_matches` says whether the register's name is the same company's."
          }
        },
        "type": "object",
        "required": [
          "vat_number"
        ],
        "title": "RegisterCheckInput",
        "description": "A VAT number to check, in the body: a sole trader's number and name are personal data and\nstay out of URLs and access logs.",
        "examples": [
          {
            "country": "DE",
            "name": "Muster Lieferant GmbH",
            "vat_number": "DE811569869"
          }
        ]
      },
      "ReimbursementInput": {
        "properties": {
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code (or id) of the company it is for, e.g. `CH01`; default: the organization's only company, else the one the person's last expense was for."
          },
          "iban": {
            "type": "string",
            "maxLength": 42,
            "minLength": 15,
            "title": "Iban",
            "description": "Your own bank account's IBAN."
          }
        },
        "type": "object",
        "required": [
          "iban"
        ],
        "title": "ReimbursementInput",
        "examples": [
          {
            "entity": "CH01",
            "iban": "CH93 0076 2011 6238 5295 7"
          }
        ]
      },
      "ReimbursementOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "vendor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor",
            "description": "The vendor you are paid back as (`V-00012`); null before your first expense."
          },
          "vendor_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Status",
            "description": "`active`, or `draft` until the AI reviewer or a person activates it."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "The account you are paid back to."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "vendor",
          "vendor_status",
          "iban"
        ],
        "title": "ReimbursementOut"
      },
      "RejectInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why the receiving entity refuses the document; the sender sees it."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "RejectInput",
        "examples": [
          {
            "reason": "The fee was agreed at 8,000, not 10,000"
          }
        ]
      },
      "RejectedPayment": {
        "properties": {
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "title": "Payment Id",
            "description": "Id of the payment the bank rejected."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number, the end-to-end id of the payment file."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "The vendor's (or customer's) name."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Its amount, in its currency."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the payment."
          },
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "The bank's reason as an ISO 20022 code, if given."
          },
          "text": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Text",
            "description": "The bank's own words, if any."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "already_reversed",
              "executed",
              "not_posted",
              "pending_approval",
              "reversal_waits",
              "reversed"
            ],
            "title": "Outcome",
            "description": "What the import did: `reversed` (the bills it paid are open again), `pending_approval` (the reversal waits for a second person), `already_reversed` or `reversal_waits` (an earlier import or a person did it: nothing again), `executed` (a bank statement line shows the bank executed it: left to a person) or `not_posted`."
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "number",
          "party",
          "amount",
          "currency",
          "code",
          "text",
          "outcome"
        ],
        "title": "RejectedPayment"
      },
      "RelationshipInput": {
        "properties": {
          "mirror_mode": {
            "type": "string",
            "enum": [
              "draft",
              "post"
            ],
            "title": "Mirror Mode",
            "description": "`draft` (default): the document made in the counterpart is a draft that a person there accepts. `post`: the system posts it at once under the system policy, a standing flow the approval authorises (a monthly management fee); never the default.",
            "default": "draft"
          },
          "tolerance_amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Tolerance Amount",
            "description": "The difference the reconciliation counts as agreed: rounding only, in `tolerance_currency`. Default `1.00`.",
            "default": "1"
          },
          "tolerance_currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tolerance Currency",
            "description": "ISO 4217 currency of the tolerance. Default: the functional currency of `entity_a` as named in the request."
          },
          "vat_group": {
            "type": "string",
            "enum": [
              "ch_vat_group",
              "de_organschaft",
              "none"
            ],
            "title": "Vat Group",
            "description": "`none` (default), `ch_vat_group` (a Swiss VAT group, Art. 13 MWSTG: two Swiss entities) or `de_organschaft` (a German tax group, § 2 para. 2 no. 2 UStG: two German entities). From `vat_group_from` the supplies between the two are outside the scope of VAT (`vat_scope` `outside`, reason `vat_group` or `organschaft`) and no VAT report or return has them. Never between a Swiss and a German entity.",
            "default": "none"
          },
          "vat_group_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Group From",
            "description": "The date from which the VAT group applies (a Swiss group starts at the beginning of a tax period, Art. 13 para. 2 MWSTG); required with a VAT group, refused without one. Documents dated before it carry VAT as usual."
          },
          "vat_group_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Group Reference",
            "description": "The registration or documentation of the group (a notice of the tax authority, the Organträger's confirmation); required with a VAT group."
          },
          "pricing_method": {
            "type": "string",
            "enum": [
              "cost_plus",
              "cup",
              "other",
              "profit_split",
              "resale_price",
              "tnmm"
            ],
            "title": "Pricing Method",
            "description": "The transfer-pricing method the approvers accepted: `cup` (comparable uncontrolled price), `resale_price`, `cost_plus`, `tnmm` (transactional net margin), `profit_split` or `other`. The system records it and never judges a price."
          },
          "markup_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1000.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Markup Percent",
            "description": "The mark-up in percent where the method has one; required for `cost_plus`."
          },
          "pricing_basis": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 3,
            "title": "Pricing Basis",
            "description": "The basis in words: the benchmark or study and its date. Mandatory: an approval without it is refused (§ 1 para. 1 AStG, OECD Model Convention Art. 9)."
          },
          "pricing_documented_on": {
            "type": "string",
            "format": "date",
            "title": "Pricing Documented On",
            "description": "The date the documentation of the prices was made (§ 90 para. 3 AO)."
          },
          "entity_a": {
            "type": "string",
            "title": "Entity A",
            "description": "Code (or id) of one entity of the pair, e.g. `CH01`."
          },
          "entity_b": {
            "type": "string",
            "title": "Entity B",
            "description": "Code (or id) of the other entity, e.g. `DE01`."
          }
        },
        "type": "object",
        "required": [
          "pricing_method",
          "pricing_basis",
          "pricing_documented_on",
          "entity_a",
          "entity_b"
        ],
        "title": "RelationshipInput",
        "examples": [
          {
            "entity_a": "CH01",
            "entity_b": "DE01",
            "markup_percent": "5",
            "mirror_mode": "draft",
            "pricing_basis": "Cost plus 5 % on the cost of the shared services, benchmark study of 2026-06-30 (median of 12 comparable service providers)",
            "pricing_documented_on": "2026-06-30",
            "pricing_method": "cost_plus",
            "tolerance_amount": "1.00",
            "tolerance_currency": "CHF",
            "vat_group": "none"
          }
        ]
      },
      "RelationshipOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the relationship."
          },
          "entity_a": {
            "type": "string",
            "title": "Entity A",
            "description": "Code of the entity whose id sorts first."
          },
          "entity_b": {
            "type": "string",
            "title": "Entity B",
            "description": "Code of the other entity."
          },
          "entity_a_name": {
            "type": "string",
            "title": "Entity A Name",
            "description": "Name of `entity_a`."
          },
          "entity_b_name": {
            "type": "string",
            "title": "Entity B Name",
            "description": "Name of `entity_b`."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "suspended"
            ],
            "title": "Status",
            "description": "`pending` (waits for a second person's approval), `active` or `suspended`."
          },
          "mirror_mode": {
            "type": "string",
            "enum": [
              "draft",
              "post"
            ],
            "title": "Mirror Mode",
            "description": "`draft` or `post`."
          },
          "tolerance_amount": {
            "type": "string",
            "title": "Tolerance Amount",
            "description": "Difference counted as agreed."
          },
          "tolerance_currency": {
            "type": "string",
            "title": "Tolerance Currency",
            "description": "Currency of the tolerance."
          },
          "vat_group": {
            "type": "string",
            "enum": [
              "ch_vat_group",
              "de_organschaft",
              "none"
            ],
            "title": "Vat Group",
            "description": "`none`, `ch_vat_group` or `de_organschaft`."
          },
          "vat_group_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Group From",
            "description": "From when the VAT group applies."
          },
          "vat_group_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Group Reference",
            "description": "Registration or documentation."
          },
          "pricing_method": {
            "type": "string",
            "enum": [
              "cost_plus",
              "cup",
              "other",
              "profit_split",
              "resale_price",
              "tnmm"
            ],
            "title": "Pricing Method",
            "description": "The transfer-pricing method."
          },
          "markup_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Markup Percent",
            "description": "The mark-up, where the method has one."
          },
          "pricing_basis": {
            "type": "string",
            "title": "Pricing Basis",
            "description": "The basis the approvers accepted."
          },
          "pricing_documented_on": {
            "type": "string",
            "format": "date",
            "title": "Pricing Documented On",
            "description": "Date of the documentation."
          },
          "terms_digest": {
            "type": "string",
            "title": "Terms Digest",
            "description": "SHA-256 of the pair and the terms the approval authorised."
          },
          "requested_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Requested By",
            "description": "Who asked for the terms in force."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved them; null while pending."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When (UTC)."
          },
          "suspended_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suspended By",
            "description": "Who suspended it, if suspended."
          },
          "suspended_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suspended At",
            "description": "When it was suspended (UTC)."
          },
          "suspend_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suspend Reason",
            "description": "Why it was suspended."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the relationship was requested (UTC)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request waiting for a second person (the first approval, a change of terms or a resumption): `POST /v1/approvals/{approval_id}/approve`, not by the person who asked. Null when nothing waits."
          },
          "pending_terms": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pending Terms",
            "description": "The terms a waiting change would put in force; null when none waits or the request is the first approval."
          },
          "parties": {
            "items": {
              "$ref": "#/components/schemas/GroupPartyOut"
            },
            "type": "array",
            "title": "Parties",
            "description": "The four customer and vendor records the approval created, two in each entity; empty until approved."
          },
          "open_mirrors": {
            "type": "integer",
            "title": "Open Mirrors",
            "description": "Mirror documents of this relationship waiting as drafts to be accepted; `GET /v1/ic/links?relationship={id}&status=drafted` lists them."
          },
          "not_made": {
            "type": "integer",
            "title": "Not Made",
            "description": "Links whose counterpart could not be made yet (`pending`; their `error` says why): `GET /v1/ic/links?relationship={id}&status=pending` lists them."
          },
          "rejected_mirrors": {
            "type": "integer",
            "title": "Rejected Mirrors",
            "description": "Links whose mirror the receiving entity rejected: `GET /v1/ic/links?relationship={id}&status=rejected` lists them."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity_a",
          "entity_b",
          "entity_a_name",
          "entity_b_name",
          "status",
          "mirror_mode",
          "tolerance_amount",
          "tolerance_currency",
          "vat_group",
          "vat_group_from",
          "vat_group_reference",
          "pricing_method",
          "markup_percent",
          "pricing_basis",
          "pricing_documented_on",
          "terms_digest",
          "requested_by",
          "approved_by",
          "approved_at",
          "suspended_by",
          "suspended_at",
          "suspend_reason",
          "created_at",
          "approval_id",
          "pending_terms",
          "parties",
          "open_mirrors",
          "not_made",
          "rejected_mirrors"
        ],
        "title": "RelationshipOut",
        "examples": [
          {
            "approved_at": "2026-09-01T09:30:00Z",
            "approved_by": {
              "id": "user:bob",
              "name": "Bob",
              "type": "human"
            },
            "created_at": "2026-09-01T09:00:00Z",
            "entity_a": "CH01",
            "entity_a_name": "Demo AG",
            "entity_b": "DE01",
            "entity_b_name": "Demo GmbH",
            "id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
            "markup_percent": "5",
            "mirror_mode": "draft",
            "not_made": 0,
            "open_mirrors": 1,
            "parties": [
              {
                "code": "IC-DE01",
                "entity": "CH01",
                "kind": "customer",
                "party_id": "1a2b3c4d-0000-4000-8000-000000000001",
                "status": "active"
              },
              {
                "code": "IC-CH01",
                "entity": "DE01",
                "kind": "vendor",
                "party_id": "1a2b3c4d-0000-4000-8000-000000000002",
                "status": "active"
              }
            ],
            "pricing_basis": "Cost plus 5 % on the cost of the shared services, benchmark study of 2026-06-30 (median of 12 comparable service providers)",
            "pricing_documented_on": "2026-06-30",
            "pricing_method": "cost_plus",
            "rejected_mirrors": 0,
            "requested_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "status": "active",
            "terms_digest": "9d1f3c0b5e7a4c2f8b6d0a1e3c5f7b9d2a4c6e8f0b1d3f5a7c9e1b3d5f7a9c0e",
            "tolerance_amount": "1.00",
            "tolerance_currency": "CHF",
            "vat_group": "none"
          }
        ]
      },
      "RelationshipReconciliation": {
        "properties": {
          "relationship_id": {
            "type": "string",
            "format": "uuid",
            "title": "Relationship Id",
            "description": "The relationship."
          },
          "entity_a": {
            "type": "string",
            "title": "Entity A",
            "description": "Code of the first entity."
          },
          "entity_b": {
            "type": "string",
            "title": "Entity B",
            "description": "Code of the second entity."
          },
          "status": {
            "type": "string",
            "enum": [
              "fail",
              "n/a",
              "pass",
              "warn"
            ],
            "title": "Status",
            "description": "`pass` (the items add up to the tolerance or less), `warn` (what differs is entirely listed timing items), `fail` (a part is unexplained) or `n/a` (the relationship is not active)."
          },
          "tolerance_amount": {
            "type": "string",
            "title": "Tolerance Amount",
            "description": "The tolerance of the relationship."
          },
          "tolerance_currency": {
            "type": "string",
            "title": "Tolerance Currency",
            "description": "Its currency."
          },
          "difference_in_tolerance_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Difference In Tolerance Currency",
            "description": "The sum of the differences of all items, each converted at the ECB closing rate of the day, in `tolerance_currency` (absolute values); null when a rate is missing. The tolerance is applied to this figure."
          },
          "unexplained_in_tolerance_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unexplained In Tolerance Currency",
            "description": "The same for the unexplained items only."
          },
          "currencies": {
            "items": {
              "$ref": "#/components/schemas/CurrencyRow"
            },
            "type": "array",
            "title": "Currencies",
            "description": "The open items per document currency."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/ItemRow"
            },
            "type": "array",
            "title": "Items",
            "description": "Every link with something open on either side and every group document nobody linked, each with its reason (null where the two sides agree); a link settled in full on both sides is left out. The differences of the items add up to `difference` of the currency rows."
          },
          "balances": {
            "items": {
              "$ref": "#/components/schemas/BalanceRow"
            },
            "type": "array",
            "title": "Balances",
            "description": "The loans, their accrued interest and the declared group dividends between the two, each with what both sides hold of it in its currency; their differences count with the items' towards the tolerance."
          },
          "carrying": {
            "items": {
              "$ref": "#/components/schemas/CarryingRow"
            },
            "type": "array",
            "title": "Carrying",
            "description": "The carrying amounts of the two entities in their functional currencies."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "The result in words."
          }
        },
        "type": "object",
        "required": [
          "relationship_id",
          "entity_a",
          "entity_b",
          "status",
          "tolerance_amount",
          "tolerance_currency",
          "difference_in_tolerance_currency",
          "unexplained_in_tolerance_currency",
          "currencies",
          "items",
          "carrying",
          "detail"
        ],
        "title": "RelationshipReconciliation"
      },
      "RelationshipUpdate": {
        "properties": {
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "active",
                  "suspended"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "`suspended` stops new intercompany postings at once (one person, with a `reason`); open items stay and settle normally. `active` on a suspended relationship asks a second person to approve resuming."
          },
          "mirror_mode": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "draft",
                  "post"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Mirror Mode",
            "description": "New mirror mode."
          },
          "tolerance_amount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tolerance Amount",
            "description": "New tolerance."
          },
          "tolerance_currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tolerance Currency",
            "description": "New tolerance currency."
          },
          "vat_group": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "ch_vat_group",
                  "de_organschaft",
                  "none"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Group",
            "description": "New VAT group."
          },
          "vat_group_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Group From",
            "description": "New VAT group start date."
          },
          "vat_group_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Group Reference",
            "description": "New VAT group reference."
          },
          "pricing_method": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "cost_plus",
                  "cup",
                  "other",
                  "profit_split",
                  "resale_price",
                  "tnmm"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Pricing Method",
            "description": "New method."
          },
          "markup_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1000.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Markup Percent",
            "description": "New mark-up."
          },
          "pricing_basis": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Pricing Basis",
            "description": "New pricing basis."
          },
          "pricing_documented_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pricing Documented On",
            "description": "New date of the documentation."
          },
          "refresh_parties": {
            "type": "boolean",
            "title": "Refresh Parties",
            "description": "Read the name, address, VAT number, country and bank accounts of the two entities again into their four customer and vendor records, which are not edited by hand. Alone: it changes no terms.",
            "default": false
          },
          "reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why: required to suspend, kept with a change of terms in the audit trail."
          }
        },
        "type": "object",
        "title": "RelationshipUpdate",
        "description": "A change to a relationship: new terms (a new approval request), a suspension or the\nre-activation of a suspended relationship (a request), or a refresh of the group parties.",
        "examples": [
          {
            "reason": "Entity DE01 is being sold",
            "status": "suspended"
          }
        ]
      },
      "RemeasurementItem": {
        "properties": {
          "contract": {
            "type": "string",
            "title": "Contract",
            "description": "Number of the revenue contract."
          },
          "contract_id": {
            "type": "string",
            "format": "uuid",
            "title": "Contract Id",
            "description": "Id of the revenue contract."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The contract's currency."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The unbilled receivable in the contract's currency."
          },
          "carrying": {
            "type": "string",
            "title": "Carrying",
            "description": "What it is carried at in the functional currency (the rates it was recognised at)."
          },
          "closing_rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Closing Rate",
            "description": "The ECB rate of the period end."
          },
          "remeasured": {
            "type": "string",
            "title": "Remeasured",
            "description": "`amount` at the closing rate."
          },
          "change": {
            "type": "string",
            "title": "Change",
            "description": "What this run posts (or would post): Dr or Cr the unbilled receivable against unrealised exchange differences, reversed on the first day of the next period."
          }
        },
        "type": "object",
        "required": [
          "contract",
          "contract_id",
          "currency",
          "amount",
          "carrying",
          "closing_rate",
          "remeasured",
          "change"
        ],
        "title": "RemeasurementItem"
      },
      "ReminderBlocked": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Invoice number."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date."
          },
          "days_overdue": {
            "type": "integer",
            "title": "Days Overdue",
            "description": "Days past the due date today (0 or less: not due)."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "What is open today."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why the reminders are stopped."
          },
          "blocked_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Blocked By",
            "description": "Who stopped them: type, id and name."
          },
          "blocked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Blocked At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "party_code",
          "party",
          "currency",
          "due_date",
          "days_overdue",
          "open",
          "reason",
          "blocked_by",
          "blocked_at"
        ],
        "title": "ReminderBlocked",
        "description": "An open invoice whose reminders a person stopped: no letter names it while the stop holds."
      },
      "ReminderChargeOut": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number; null while it waits for approval."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, `pending_approval`, `rejected` (by the approver, or withdrawn from approval), `draft` (a rejected invoice reopened) or `void` (reopened and voided)."
          },
          "charged": {
            "type": "boolean",
            "title": "Charged",
            "description": "False once the invoice is rejected or void: the letter's charges were not booked, and a later letter charges the same interest days and flat fees again."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "status",
          "charged"
        ],
        "title": "ReminderChargeOut",
        "description": "The sales invoice that books a letter's fees and interest, made at its first hand-over."
      },
      "ReminderCreateInput": {
        "properties": {
          "as_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "As Of",
            "description": "The day of the letter: today in the entity's country, the only day a letter is dated (its amounts are today's). Omitted: today."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 3,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The currency of the letter. Omitted: the one the customer (or the invoices named) is due a reminder in; of several, the customer's own (422 `reminder_currency_needed` when it is not one of them)."
          },
          "documents": {
            "anyOf": [
              {
                "items": {
                  "type": "string",
                  "format": "uuid"
                },
                "type": "array",
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Documents",
            "description": "Only these invoices (each must be due a reminder); omitted: every invoice of the customer in the currency that is due one."
          },
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "sv"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Language of the letter; omitted: the customer's language."
          }
        },
        "type": "object",
        "title": "ReminderCreateInput",
        "examples": [
          {},
          {
            "currency": "CHF",
            "documents": [
              "3fa85f64-5717-4562-b3fc-2c963f66afa6"
            ]
          }
        ]
      },
      "ReminderCredit": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "payment_on_account",
              "sales_credit_note"
            ],
            "title": "Kind",
            "description": "`sales_credit_note`, or `payment_on_account`: what is left on account of a receipt, not yet applied to an invoice."
          },
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the credit note, or of the receipt."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Number of the credit note or the receipt."
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "Date of the credit note or the receipt."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "What the letter deducts of it (positive): what is left of it today, less what letters still standing deducted already. An application waiting for approval reserves its amount."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "document_id",
          "number",
          "date",
          "open"
        ],
        "title": "ReminderCredit",
        "description": "What the customer has to its credit in the letter's currency, deducted from what the letter\nasks for: a credit note with something open, or a receipt's amount on account (ADR-0045).\nEach credit is deducted once: what a letter still standing (not withdrawn, naming an invoice\nstill open that no later letter names) deducted is not deducted again."
      },
      "ReminderDispatchOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the hand-over."
          },
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "portal",
              "post",
              "system_email"
            ],
            "title": "Channel",
            "description": "`system_email` (this server sent it) or what a person recorded: `email`, `post`, `portal`, `other`."
          },
          "handed_over_on": {
            "type": "string",
            "format": "date",
            "title": "Handed Over On",
            "description": "The day it was handed over."
          },
          "recipients": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recipients",
            "description": "To whom."
          },
          "subject": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject",
            "description": "Subject of the e-mail; null for a recorded one."
          },
          "message_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Message Id",
            "description": "`Message-ID` of the e-mail; null otherwise."
          },
          "sent_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Sent By",
            "description": "Who: type, id and name."
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "title": "Sent At",
            "description": "When it was sent or recorded (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "channel",
          "handed_over_on",
          "recipients",
          "subject",
          "message_id",
          "sent_by",
          "sent_at"
        ],
        "title": "ReminderDispatchOut"
      },
      "ReminderDue": {
        "properties": {
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency of the letter."
          },
          "level": {
            "type": "integer",
            "title": "Level",
            "description": "The letter's level: the highest next level of its invoices."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The customer's language: that of the letter."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "What the letter would ask for: the invoices' open amounts less `credits`, plus `fee` and the flat fees and interest of the invoices. A customer whose credits cover its overdue invoices is due no letter."
          },
          "fee": {
            "type": "string",
            "title": "Fee",
            "description": "The fee of the letter's level, in its currency (converted from the functional currency at today's rate); 0 for none.",
            "default": "0.00"
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Where an e-mail would go by default: the customer's billing address."
          },
          "invoices": {
            "items": {
              "$ref": "#/components/schemas/ReminderInvoice"
            },
            "type": "array",
            "title": "Invoices",
            "description": "The invoices due a reminder."
          },
          "credits": {
            "items": {
              "$ref": "#/components/schemas/ReminderCredit"
            },
            "type": "array",
            "title": "Credits",
            "description": "The customer's credit notes with something open and receipts' amounts on account in the currency, as far as no letter still standing deducted them, which the letter deducts."
          }
        },
        "type": "object",
        "required": [
          "party_id",
          "party_code",
          "party",
          "currency",
          "level",
          "language",
          "total",
          "email",
          "invoices"
        ],
        "title": "ReminderDue",
        "description": "A customer that is due a reminder letter in one currency."
      },
      "ReminderFile": {
        "properties": {
          "file_id": {
            "type": "string",
            "format": "uuid",
            "title": "File Id",
            "description": "Id of the archived file (`document.id`)."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "File name, e.g. `reminder-C-DE-2026-10-10-1.pdf`."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the archived bytes."
          },
          "size": {
            "type": "integer",
            "title": "Size",
            "description": "Size in bytes."
          }
        },
        "type": "object",
        "required": [
          "file_id",
          "filename",
          "sha256",
          "size"
        ],
        "title": "ReminderFile",
        "description": "The archived PDF of a letter."
      },
      "ReminderInvoice": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Invoice number."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Invoice date."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date."
          },
          "days_overdue": {
            "type": "integer",
            "title": "Days Overdue",
            "description": "Days past the due date today."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "What is open today, in the invoice's currency."
          },
          "last_level": {
            "type": "integer",
            "title": "Last Level",
            "description": "The level of the last letter that named it; 0 for none."
          },
          "last_sent_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Sent On",
            "description": "The day that letter was first handed over; null when none was, or never."
          },
          "next_level": {
            "type": "integer",
            "title": "Next Level",
            "description": "The level the next letter gives it."
          },
          "flat_fee": {
            "type": "string",
            "title": "Flat Fee",
            "description": "The flat fee the letter charges once for this invoice (a business customer; Germany: EUR 40, § 288 para. 5 BGB), in its currency; 0 for none.",
            "default": "0.00"
          },
          "interest": {
            "type": "string",
            "title": "Interest",
            "description": "Default interest the letter charges on this invoice, in its currency: actual/365 on what was open each day from `interest_from` (exclusive) to `interest_until`; 0 for none.",
            "default": "0.00"
          },
          "interest_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interest Rate",
            "description": "The yearly rate in percent (when it changed in the span, that of the letter's day: see `interest_parts`); null when no interest is charged."
          },
          "interest_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interest From",
            "description": "The interest runs from the day after this one: the due date, or the last day an earlier letter charged interest for (no day is charged twice)."
          },
          "interest_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interest Until",
            "description": "The last day the interest covers: the letter's day."
          },
          "interest_parts": {
            "items": {
              "$ref": "#/components/schemas/InterestPart"
            },
            "type": "array",
            "title": "Interest Parts",
            "description": "When the rate changed in the span (the German base rate on 1 January or 1 July), the parts at each rate, in order, adding up to `interest`; empty when one rate covers it all."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "document_date",
          "due_date",
          "days_overdue",
          "currency",
          "open",
          "last_level",
          "last_sent_on",
          "next_level"
        ],
        "title": "ReminderInvoice",
        "description": "An overdue invoice and where its reminders stand."
      },
      "ReminderItemOut": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Invoice number."
          },
          "level": {
            "type": "integer",
            "title": "Level",
            "description": "The level the invoice reached with this letter."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Its due date."
          },
          "days_overdue": {
            "type": "integer",
            "title": "Days Overdue",
            "description": "Days past the due date on the letter's day."
          },
          "open_amount": {
            "type": "string",
            "title": "Open Amount",
            "description": "What was open on the letter's day."
          },
          "flat_fee": {
            "type": "string",
            "title": "Flat Fee",
            "description": "The flat fee charged for it.",
            "default": "0.00"
          },
          "interest": {
            "type": "string",
            "title": "Interest",
            "description": "The default interest charged on it.",
            "default": "0.00"
          },
          "interest_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interest Rate",
            "description": "Yearly rate in percent."
          },
          "interest_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interest From",
            "description": "The interest runs from the day after this one."
          },
          "interest_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Interest Until",
            "description": "The last day the interest covers."
          },
          "interest_parts": {
            "items": {
              "$ref": "#/components/schemas/InterestPart"
            },
            "type": "array",
            "title": "Interest Parts",
            "description": "When the rate changed in the span (the German base rate on 1 January or 1 July), the parts at each rate, in order, adding up to `interest`; empty when one rate covers it all."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "level",
          "due_date",
          "days_overdue",
          "open_amount"
        ],
        "title": "ReminderItemOut"
      },
      "ReminderLevelFees-Input": {
        "properties": {
          "level": {
            "type": "integer",
            "maximum": 3.0,
            "minimum": 1.0,
            "title": "Level",
            "description": "1 payment reminder, 2 second, 3 final reminder."
          },
          "fee": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Fee",
            "description": "Fee per letter of this level, in the company's functional currency (a letter in another currency converts it at the letter's day); 0 for none."
          },
          "flat_fee": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Flat Fee",
            "description": "Flat fee charged once per invoice to a business customer, in the functional currency (Germany: EUR 40 on the first reminder, § 288 para. 5 BGB); 0 for none. When the charge of the letter that set it is rejected or voided, the next letter charges it."
          },
          "interest_rate": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,5}|(?=[\\d.]{1,10}0*$)\\d{0,5}\\.\\d{0,4}0*$)"
              }
            ],
            "title": "Interest Rate",
            "description": "Default interest for business customers, percent a year (actual/365), from the due date; 0 for none."
          },
          "consumer_interest_rate": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,5}|(?=[\\d.]{1,10}0*$)\\d{0,5}\\.\\d{0,4}0*$)"
              }
            ],
            "title": "Consumer Interest Rate",
            "description": "Default interest for consumers (customers that are not a business), percent a year; 0 for none."
          }
        },
        "type": "object",
        "required": [
          "level",
          "fee",
          "flat_fee",
          "interest_rate",
          "consumer_interest_rate"
        ],
        "title": "ReminderLevelFees",
        "description": "What a reminder of one level charges."
      },
      "ReminderLevelFees-Output": {
        "properties": {
          "level": {
            "type": "integer",
            "maximum": 3.0,
            "minimum": 1.0,
            "title": "Level",
            "description": "1 payment reminder, 2 second, 3 final reminder."
          },
          "fee": {
            "type": "string",
            "title": "Fee",
            "description": "Fee per letter of this level, in the company's functional currency (a letter in another currency converts it at the letter's day); 0 for none."
          },
          "flat_fee": {
            "type": "string",
            "title": "Flat Fee",
            "description": "Flat fee charged once per invoice to a business customer, in the functional currency (Germany: EUR 40 on the first reminder, § 288 para. 5 BGB); 0 for none. When the charge of the letter that set it is rejected or voided, the next letter charges it."
          },
          "interest_rate": {
            "type": "string",
            "title": "Interest Rate",
            "description": "Default interest for business customers, percent a year (actual/365), from the due date; 0 for none."
          },
          "consumer_interest_rate": {
            "type": "string",
            "title": "Consumer Interest Rate",
            "description": "Default interest for consumers (customers that are not a business), percent a year; 0 for none."
          }
        },
        "type": "object",
        "required": [
          "level",
          "fee",
          "flat_fee",
          "interest_rate",
          "consumer_interest_rate"
        ],
        "title": "ReminderLevelFees",
        "description": "What a reminder of one level charges."
      },
      "ReminderMarkSentInput": {
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "portal",
              "post"
            ],
            "title": "Channel",
            "description": "`email` (from a person's own mailbox), `post`, `portal` or `other`."
          },
          "recipient": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Recipient",
            "description": "Who got it."
          },
          "handed_over_on": {
            "type": "string",
            "format": "date",
            "title": "Handed Over On",
            "description": "The day it was handed over: not before the letter, not after today, and within the last 7 days."
          }
        },
        "type": "object",
        "required": [
          "channel",
          "recipient",
          "handed_over_on"
        ],
        "title": "ReminderMarkSentInput",
        "examples": [
          {
            "channel": "post",
            "handed_over_on": "2026-10-10",
            "recipient": "Berlin GmbH"
          }
        ]
      },
      "ReminderOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the letter."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "level": {
            "type": "integer",
            "title": "Level",
            "description": "1 payment reminder, 2 second reminder, 3 final reminder."
          },
          "letter_date": {
            "type": "string",
            "format": "date",
            "title": "Letter Date",
            "description": "The day of the letter."
          },
          "deadline_date": {
            "type": "string",
            "format": "date",
            "title": "Deadline Date",
            "description": "The day by which it asks for payment."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of the letter."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "What it asks for: the open amounts of its invoices less the customer's credits it deducts, plus its fee and the flat fees and interest of its invoices, on the letter's day."
          },
          "fee": {
            "type": "string",
            "title": "Fee",
            "description": "The fee of its level; 0 for none.",
            "default": "0.00"
          },
          "charge": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReminderChargeOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The sales invoice of its fees and interest (outside VAT), made when it was first handed over; null before, or when it charges nothing."
          },
          "file": {
            "$ref": "#/components/schemas/ReminderFile",
            "description": "The archived PDF."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/ReminderItemOut"
            },
            "type": "array",
            "title": "Items",
            "description": "The invoices it names."
          },
          "dispatches": {
            "items": {
              "$ref": "#/components/schemas/ReminderDispatchOut"
            },
            "type": "array",
            "title": "Dispatches",
            "description": "Each hand-over, oldest first. Empty: made but not sent, which starts no clock for the next level."
          },
          "state": {
            "type": "string",
            "enum": [
              "handed_over",
              "out_of_date",
              "unsent",
              "withdrawn"
            ],
            "title": "State",
            "description": "`unsent` (made, not handed over, still right: send or record it), `out_of_date` (not handed over, and an amount on it changed since or it is more than 7 days old: it cannot be sent; withdraw it and make a new one), `handed_over` or `withdrawn`."
          },
          "withdrawal": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReminderWithdrawalOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who withdrew it, when and why; null when nobody did."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "Where an e-mail would go by default: the customer's billing address."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "party_id",
          "party_code",
          "party",
          "currency",
          "level",
          "letter_date",
          "deadline_date",
          "language",
          "total",
          "file",
          "created_by",
          "created_at",
          "items",
          "dispatches",
          "state",
          "email"
        ],
        "title": "ReminderOut",
        "description": "A reminder letter: what it asked for, its file and its hand-overs."
      },
      "ReminderProposal": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "Today, in the entity's country: the day of the letters."
          },
          "levels": {
            "items": {
              "$ref": "#/components/schemas/DunningLevelOut"
            },
            "type": "array",
            "title": "Levels",
            "description": "The levels and when each is due."
          },
          "due": {
            "items": {
              "$ref": "#/components/schemas/ReminderDue"
            },
            "type": "array",
            "title": "Due",
            "description": "One row per customer and currency that is due a letter, by customer code."
          },
          "unsent": {
            "items": {
              "$ref": "#/components/schemas/ReminderOut"
            },
            "type": "array",
            "title": "Unsent",
            "description": "Letters made, not handed over yet and still right: send or record them, or the next level never comes."
          },
          "out_of_date": {
            "items": {
              "$ref": "#/components/schemas/ReminderOut"
            },
            "type": "array",
            "title": "Out Of Date",
            "description": "Letters not handed over that are out of date (an amount on them changed, or they are more than 7 days old): they cannot be sent and hold back the next letter until they are withdrawn."
          },
          "blocked": {
            "items": {
              "$ref": "#/components/schemas/ReminderBlocked"
            },
            "type": "array",
            "title": "Blocked",
            "description": "Open invoices whose reminders a person stopped (a dispute): left out of every letter, with why."
          },
          "sending_configured": {
            "type": "boolean",
            "title": "Sending Configured",
            "description": "Whether this server sends e-mail (false in a test copy, which never does)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "as_of",
          "levels",
          "due",
          "unsent",
          "sending_configured"
        ],
        "title": "ReminderProposal",
        "description": "Which customers are due a reminder letter today, and the letters not yet sent."
      },
      "ReminderSendInput": {
        "properties": {
          "to": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 5,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "To",
            "description": "Addresses of the customer (as for an invoice); omitted: its billing address."
          },
          "message": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "A text placed before the standard text."
          }
        },
        "type": "object",
        "title": "ReminderSendInput",
        "examples": [
          {},
          {
            "to": [
              "buchhaltung@berlin-gmbh.example"
            ]
          }
        ]
      },
      "ReminderSettingsInput": {
        "properties": {
          "levels": {
            "items": {
              "$ref": "#/components/schemas/ReminderLevelFees-Input"
            },
            "type": "array",
            "maxItems": 3,
            "minItems": 3,
            "title": "Levels",
            "description": "The three levels, each once."
          }
        },
        "type": "object",
        "required": [
          "levels"
        ],
        "title": "ReminderSettingsInput",
        "examples": [
          {
            "levels": [
              {
                "consumer_interest_rate": "5",
                "fee": "0",
                "flat_fee": "0",
                "interest_rate": "5",
                "level": 1
              },
              {
                "consumer_interest_rate": "5",
                "fee": "20",
                "flat_fee": "0",
                "interest_rate": "5",
                "level": 2
              },
              {
                "consumer_interest_rate": "5",
                "fee": "30",
                "flat_fee": "0",
                "interest_rate": "5",
                "level": 3
              }
            ]
          }
        ]
      },
      "ReminderSettingsOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The functional currency the fees are in."
          },
          "configured": {
            "type": "boolean",
            "title": "Configured",
            "description": "Whether a person saved settings; false: the country's defaults apply."
          },
          "levels": {
            "items": {
              "$ref": "#/components/schemas/ReminderLevelFees-Output"
            },
            "type": "array",
            "title": "Levels",
            "description": "The three levels, in order."
          },
          "defaults": {
            "items": {
              "$ref": "#/components/schemas/ReminderLevelFees-Output"
            },
            "type": "array",
            "title": "Defaults",
            "description": "The country's defaults: Switzerland and Liechtenstein 5 % a year and no fee; Germany the base rate plus 9 points (business) or 5 points (consumers), shown at today's base rate and charged at each day's (split where it changes, on 1 January or 1 July), and EUR 40 once per invoice to a business customer; elsewhere nothing."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "configured",
          "levels",
          "defaults"
        ],
        "title": "ReminderSettingsOut",
        "description": "The fees and default interest of each reminder level of a company."
      },
      "ReminderWithdrawInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why it is withdrawn."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "ReminderWithdrawInput",
        "examples": [
          {
            "reason": "The customer paid part of it meanwhile"
          }
        ]
      },
      "ReminderWithdrawalOut": {
        "properties": {
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why it was withdrawn."
          },
          "withdrawn_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Withdrawn By",
            "description": "Who: type, id and name."
          },
          "withdrawn_at": {
            "type": "string",
            "format": "date-time",
            "title": "Withdrawn At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "reason",
          "withdrawn_by",
          "withdrawn_at"
        ],
        "title": "ReminderWithdrawalOut"
      },
      "ReopenInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why the period is reopened (audit trail)."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "ReopenInput",
        "examples": [
          {
            "reason": "Late audit adjustment to the September accruals"
          }
        ]
      },
      "ReplyInput": {
        "properties": {
          "body": {
            "type": "string",
            "maxLength": 100000,
            "minLength": 1,
            "title": "Body",
            "description": "The reply."
          },
          "to": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 10
              },
              {
                "type": "null"
              }
            ],
            "title": "To",
            "description": "Recipients: the requester's, the contact's or the customer's addresses; none: the requester (or the contact)."
          },
          "action": {
            "type": "string",
            "enum": [
              "draft",
              "record",
              "send"
            ],
            "title": "Action",
            "description": "`draft`: keep it for a person to send; `send`: e-mail it now; `record`: it was answered elsewhere (phone, another mailbox) and is recorded as sent. Only a person sends or records.",
            "default": "draft"
          },
          "then": {
            "type": "string",
            "enum": [
              "closed",
              "open",
              "waiting"
            ],
            "title": "Then",
            "description": "The case's status once sent or recorded.",
            "default": "waiting"
          }
        },
        "type": "object",
        "required": [
          "body"
        ],
        "title": "ReplyInput",
        "examples": [
          {
            "action": "send",
            "body": "Dear Ms Muster,\n\nwe corrected the address and sent the invoice again.\n\nKind regards",
            "then": "waiting"
          }
        ]
      },
      "ReplySendInput": {
        "properties": {
          "via": {
            "type": "string",
            "enum": [
              "email",
              "outside"
            ],
            "title": "Via",
            "description": "`email`: send it from here; `outside`: it was answered elsewhere.",
            "default": "email"
          },
          "then": {
            "type": "string",
            "enum": [
              "closed",
              "open",
              "waiting"
            ],
            "title": "Then",
            "description": "The case's status afterwards.",
            "default": "waiting"
          }
        },
        "type": "object",
        "title": "ReplySendInput",
        "examples": [
          {
            "then": "waiting",
            "via": "email"
          }
        ]
      },
      "ReportColumn": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The field, as in the definition."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "Its heading, in the language asked for."
          },
          "type": {
            "type": "string",
            "title": "Type",
            "description": "What it holds, as a source's field says (`money`, `date` …)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Of an amount: the field of its currency, or null for the company's."
          }
        },
        "type": "object",
        "required": [
          "name",
          "label",
          "type",
          "currency"
        ],
        "title": "ReportColumn"
      },
      "ReportDefinition": {
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "bills",
              "customers",
              "deals",
              "journal_lines",
              "leads",
              "payments",
              "products",
              "purchase_orders",
              "sales_invoices",
              "subscriptions",
              "vendors"
            ],
            "title": "Source",
            "description": "The kind of record the report lists (`GET /v1/saved-report-sources` lists each with its fields)."
          },
          "columns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 12,
            "title": "Columns",
            "description": "The fields shown, in order; empty: the source's usual ones."
          },
          "filters": {
            "items": {
              "$ref": "#/components/schemas/ReportFilter"
            },
            "type": "array",
            "maxItems": 16,
            "title": "Filters",
            "description": "The conditions a row meets, all of them."
          },
          "group_by": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Group By",
            "description": "A field to group the rows by: one line per value, with the count and the sums. Amounts in a record's own currency are grouped per currency as well."
          },
          "sums": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 4,
            "title": "Sums",
            "description": "The amounts or numbers added up for each group and in the totals; empty: the source's main amount."
          },
          "sort": {
            "items": {
              "$ref": "#/components/schemas/ReportSort"
            },
            "type": "array",
            "maxItems": 3,
            "title": "Sort",
            "description": "The order."
          },
          "limit": {
            "type": "integer",
            "maximum": 500.0,
            "minimum": 1.0,
            "title": "Limit",
            "description": "Rows or groups shown, at most 500.",
            "default": 100
          }
        },
        "type": "object",
        "required": [
          "source"
        ],
        "title": "ReportDefinition",
        "examples": [
          {
            "filters": [
              {
                "field": "kind",
                "op": "eq",
                "value": "sales_invoice"
              },
              {
                "field": "payment",
                "op": "in",
                "value": [
                  "open",
                  "overdue"
                ]
              },
              {
                "field": "open_amount",
                "op": "gt",
                "value": "10000"
              },
              {
                "field": "country",
                "op": "eq",
                "value": "DE"
              }
            ],
            "group_by": "sales_person",
            "source": "sales_invoices",
            "sums": [
              "open_amount"
            ]
          }
        ]
      },
      "ReportFilter": {
        "properties": {
          "field": {
            "type": "string",
            "maxLength": 40,
            "title": "Field",
            "description": "A field of the source, e.g. `open_amount`."
          },
          "op": {
            "type": "string",
            "enum": [
              "between",
              "contains",
              "empty",
              "eq",
              "gt",
              "gte",
              "in",
              "lt",
              "lte",
              "ne",
              "not_in",
              "set"
            ],
            "title": "Op",
            "description": "`eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in` and `not_in` (a list), `contains` (text), `between` (a list of two, both included), `empty` or `set` (no value).",
            "default": "eq"
          },
          "value": {
            "title": "Value",
            "description": "What the field is compared with: a text, a number or amount as a string, `true`/`false`, a list for `in`, `not_in` and `between`. A date is `2026-10-01` or one counted from the company's today: `today`, `today-30`, `today+7`, `start_of_week`, `start_of_month`, `end_of_month`, `start_of_quarter`, `end_of_quarter`, `start_of_year`, `end_of_year`, `start_of_last_month`, `end_of_last_month`, `start_of_last_quarter`, `end_of_last_quarter`, `start_of_last_year`, `end_of_last_year`. A person is `me` (who reads the report), a name, an e-mail or an id."
          }
        },
        "type": "object",
        "required": [
          "field"
        ],
        "title": "ReportFilter"
      },
      "ReportGroup": {
        "properties": {
          "value": {
            "title": "Value",
            "description": "The value grouped by; null for the rows without one."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "How the value reads."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The currency of the group's amounts, if any."
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Rows in the group."
          },
          "sums": {
            "additionalProperties": {
              "type": "string",
              "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
            },
            "type": "object",
            "title": "Sums",
            "description": "The sum of each field added up, by its name."
          },
          "drill": {
            "$ref": "#/components/schemas/ReportDefinition",
            "description": "The report of the group's rows: the same report narrowed to the value, not grouped."
          }
        },
        "type": "object",
        "required": [
          "value",
          "label",
          "currency",
          "count",
          "sums",
          "drill"
        ],
        "title": "ReportGroup"
      },
      "ReportOwner": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The person's user id."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The person's name, else their e-mail."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "title": "ReportOwner"
      },
      "ReportResult": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "source": {
            "type": "string",
            "enum": [
              "bills",
              "customers",
              "deals",
              "journal_lines",
              "leads",
              "payments",
              "products",
              "purchase_orders",
              "sales_invoices",
              "subscriptions",
              "vendors"
            ],
            "title": "Source",
            "description": "What the report lists."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "The source's name in the language asked for."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The company's today the report was run on."
          },
          "company_currency": {
            "type": "string",
            "title": "Company Currency",
            "description": "The currency the company keeps its books in."
          },
          "columns": {
            "items": {
              "$ref": "#/components/schemas/ReportColumn"
            },
            "type": "array",
            "title": "Columns",
            "description": "The columns of the rows, in order."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/ReportRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "The rows, when the report is not grouped."
          },
          "groups": {
            "items": {
              "$ref": "#/components/schemas/ReportGroup"
            },
            "type": "array",
            "title": "Groups",
            "description": "The groups, when it is."
          },
          "group_by": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportColumn"
              },
              {
                "type": "null"
              }
            ],
            "description": "The field grouped by; null: not grouped."
          },
          "sums": {
            "items": {
              "$ref": "#/components/schemas/ReportColumn"
            },
            "type": "array",
            "title": "Sums",
            "description": "The fields the groups and totals add up."
          },
          "totals": {
            "items": {
              "$ref": "#/components/schemas/ReportTotal"
            },
            "type": "array",
            "title": "Totals",
            "description": "Of every row found, per currency."
          },
          "found": {
            "type": "integer",
            "title": "Found",
            "description": "Rows found in all (or groups, when grouped)."
          },
          "truncated": {
            "type": "boolean",
            "title": "Truncated",
            "description": "More were found than `limit` shows."
          },
          "definition": {
            "$ref": "#/components/schemas/ReportDefinition",
            "description": "The report as it was run, completed."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "source",
          "title",
          "as_of",
          "company_currency",
          "columns",
          "rows",
          "groups",
          "group_by",
          "sums",
          "totals",
          "found",
          "truncated",
          "definition"
        ],
        "title": "ReportResult"
      },
      "ReportRow": {
        "properties": {
          "values": {
            "additionalProperties": true,
            "type": "object",
            "title": "Values",
            "description": "The value of each column (amounts and numbers as strings, dates as ISO days); a list's value as stored, its words in `labels`."
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Labels",
            "description": "The words of the list values of the row."
          },
          "path": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Path",
            "description": "Where the row opens in the app, e.g. `/documents/…`."
          }
        },
        "type": "object",
        "required": [
          "values",
          "labels",
          "path"
        ],
        "title": "ReportRow"
      },
      "ReportSchedule": {
        "properties": {
          "every": {
            "type": "string",
            "enum": [
              "day",
              "month",
              "week"
            ],
            "title": "Every",
            "description": "How often it is sent: each `day`, `week` or `month`.",
            "default": "week"
          },
          "weekday": {
            "type": "integer",
            "maximum": 6.0,
            "minimum": 0.0,
            "title": "Weekday",
            "description": "For `week`: 0 Monday (the default) to 6 Sunday.",
            "default": 0
          },
          "day": {
            "type": "integer",
            "maximum": 28.0,
            "minimum": 1.0,
            "title": "Day",
            "description": "For `month`: the day, 1 to 28.",
            "default": 1
          },
          "hour": {
            "type": "integer",
            "maximum": 23.0,
            "minimum": 0.0,
            "title": "Hour",
            "description": "The hour in the company's time zone (default 7).",
            "default": 7
          },
          "recipients": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "maxItems": 50,
            "title": "Recipients",
            "description": "Who gets it (user ids): the owner and the people it is shared with; empty: the owner."
          }
        },
        "type": "object",
        "title": "ReportSchedule"
      },
      "ReportSendOut": {
        "properties": {
          "sent": {
            "type": "integer",
            "title": "Sent",
            "description": "E-mails sent."
          },
          "skipped": {
            "type": "integer",
            "title": "Skipped",
            "description": "Recipients not sent to (no mail server, a test copy)."
          },
          "problem": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Problem",
            "description": "Why nothing was sent, if so."
          }
        },
        "type": "object",
        "required": [
          "sent",
          "skipped",
          "problem"
        ],
        "title": "ReportSendOut"
      },
      "ReportSharing": {
        "properties": {
          "everyone": {
            "type": "boolean",
            "title": "Everyone",
            "description": "Everyone in the organization may open the report.",
            "default": false
          },
          "people": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "maxItems": 50,
            "title": "People",
            "description": "People of the organization the report is shared with (user ids)."
          }
        },
        "type": "object",
        "title": "ReportSharing"
      },
      "ReportSort": {
        "properties": {
          "by": {
            "type": "string",
            "maxLength": 40,
            "title": "By",
            "description": "A field; in a grouped report also `count` or one of its `sums`."
          },
          "descending": {
            "type": "boolean",
            "title": "Descending",
            "description": "Largest or latest first.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "by"
        ],
        "title": "ReportSort"
      },
      "ReportSourceField": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The field's name in a definition, e.g. `open_amount`."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "What the field is, in the language asked for."
          },
          "type": {
            "type": "string",
            "enum": [
              "bool",
              "country",
              "date",
              "enum",
              "money",
              "number",
              "person",
              "text"
            ],
            "title": "Type",
            "description": "What it holds: `money` an amount, `enum` one of `values`, `person` someone of the organization (`me` in a filter), `country` an ISO code."
          },
          "values": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Values",
            "description": "Of a list (`enum`): its values."
          },
          "value_labels": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Value Labels",
            "description": "The words of each value."
          },
          "group": {
            "type": "boolean",
            "title": "Group",
            "description": "A report may group by it."
          },
          "default": {
            "type": "boolean",
            "title": "Default",
            "description": "Shown when a report names no columns."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Of an amount in the record's own currency: the field that holds it; null: the company's currency."
          }
        },
        "type": "object",
        "required": [
          "name",
          "label",
          "type",
          "values",
          "value_labels",
          "group",
          "default",
          "currency"
        ],
        "title": "ReportSourceField"
      },
      "ReportSourceOut": {
        "properties": {
          "name": {
            "type": "string",
            "enum": [
              "bills",
              "customers",
              "deals",
              "journal_lines",
              "leads",
              "payments",
              "products",
              "purchase_orders",
              "sales_invoices",
              "subscriptions",
              "vendors"
            ],
            "title": "Name",
            "description": "The source's name in a definition."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "What it lists, in the language asked for."
          },
          "fields": {
            "items": {
              "$ref": "#/components/schemas/ReportSourceField"
            },
            "type": "array",
            "title": "Fields",
            "description": "What a report of it may show and filter."
          },
          "sum": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sum",
            "description": "The amount a grouped report adds up by default."
          }
        },
        "type": "object",
        "required": [
          "name",
          "label",
          "fields",
          "sum"
        ],
        "title": "ReportSourceOut"
      },
      "ReportTotal": {
        "properties": {
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "Of the amounts in the records' own currency."
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "Rows found in this currency (or in all)."
          },
          "sums": {
            "additionalProperties": {
              "type": "string",
              "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
            },
            "type": "object",
            "title": "Sums",
            "description": "The sum of each field added up, by its name."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "count",
          "sums"
        ],
        "title": "ReportTotal"
      },
      "ReportTranslation": {
        "properties": {
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The company's own currency."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency the report is shown in."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Who publishes the rates: the ECB's reference rates."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "The version of the reference data used."
          },
          "closing_rate": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DayRate"
              },
              {
                "type": "null"
              }
            ],
            "description": "Balance sheet: the rate of the report date, for assets and liabilities."
          },
          "average_rates": {
            "items": {
              "$ref": "#/components/schemas/AverageRate"
            },
            "type": "array",
            "title": "Average Rates",
            "description": "The average rate of each month with income or expenses."
          },
          "historical_rates": {
            "items": {
              "$ref": "#/components/schemas/DayRate"
            },
            "type": "array",
            "title": "Historical Rates",
            "description": "Balance sheet: the rate of each day equity was booked on."
          },
          "difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Difference",
            "description": "Balance sheet: the translation difference, the amount in equity that comes from translating at different rates (IAS 21.41); positive is a gain."
          },
          "reconciled": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reconciled",
            "description": "Balance sheet: true when the translation difference equals, to the last digit, what the movements of the rates explain (the roll-forward of the consolidation)."
          }
        },
        "type": "object",
        "required": [
          "functional_currency",
          "currency",
          "source",
          "dataset_version",
          "average_rates"
        ],
        "title": "ReportTranslation",
        "description": "How the amounts were translated, and with which rates."
      },
      "RequiredAccount": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company the account belongs to."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Code of the account, e.g. `6000`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The account's name in the user's language."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "account",
          "name"
        ],
        "title": "RequiredAccount"
      },
      "RequiredAccountsInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company whose accounts these are."
          },
          "accounts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Accounts",
            "description": "Every account of the company that requires the dimension, by code: the list replaces the one before; empty: none."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "accounts"
        ],
        "title": "RequiredAccountsInput",
        "examples": [
          {
            "accounts": [
              "6000",
              "6500"
            ],
            "entity": "CH01"
          }
        ]
      },
      "ResetInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the reconciliation is reset (required, at most 500 characters): on the record and in the audit trail."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "ResetInput",
        "examples": [
          {
            "reason": "Bank balance typed as 113,900.00"
          }
        ]
      },
      "RevaluationInput": {
        "properties": {
          "revaluation_date": {
            "type": "string",
            "format": "date",
            "title": "Revaluation Date",
            "description": "Day of the revaluation, ISO 8601; the entry is dated on it and its period must be open."
          },
          "fair_value": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Fair Value",
            "description": "The asset's fair value on that day, in the company's currency."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "The basis of the fair value, e.g. a valuer's report (kept with the change)."
          }
        },
        "type": "object",
        "required": [
          "revaluation_date",
          "fair_value",
          "reason"
        ],
        "title": "RevaluationInput",
        "examples": [
          {
            "fair_value": "15000.00",
            "reason": "Valuation report of 20 December 2026",
            "revaluation_date": "2026-12-31"
          }
        ]
      },
      "RevenueContractInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Code (or id) of the customer."
          },
          "title": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Title",
            "description": "What the contract is."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first day of the contract."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "The last day of the contract."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code of the currency the contract is priced and billed in; default the entity's functional currency. Revenue is recognised in the functional currency: what was billed in advance at the rate it was billed at, what is recognised before it is billed at the rate of the period end (ADR-0050)."
          },
          "transaction_price": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Transaction Price",
            "description": "Fixed consideration, net of VAT, in the contract's currency."
          },
          "right_to_consideration": {
            "type": "string",
            "enum": [
              "conditional",
              "unconditional"
            ],
            "title": "Right To Consideration",
            "description": "Whether a debit position (revenue before billing) is a contract asset (`conditional`, the default: the right depends on more than time) or an unbilled receivable (`unconditional`, with `right_basis`); IFRS 15.107-108.",
            "default": "conditional"
          },
          "right_basis": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Right Basis",
            "description": "Why the right is unconditional."
          },
          "obligations": {
            "items": {
              "$ref": "#/components/schemas/ObligationInput"
            },
            "type": "array",
            "maxItems": 50,
            "minItems": 1,
            "title": "Obligations",
            "description": "What the contract promises."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "party",
          "title",
          "start_date",
          "end_date",
          "transaction_price",
          "obligations"
        ],
        "title": "RevenueContractInput",
        "examples": [
          {
            "end_date": "2027-12-31",
            "entity": "CH01",
            "obligations": [
              {
                "description": "Platform subscription",
                "method": "monthly",
                "pattern": "over_time",
                "ssp": "11000.00",
                "ssp_basis": "List price, sold without discount"
              },
              {
                "description": "Onboarding",
                "pattern": "point_in_time",
                "ssp": "2000.00",
                "ssp_basis": "Day rate times days, sold separately"
              }
            ],
            "party": "C-CH",
            "start_date": "2027-01-01",
            "title": "Platform 2027",
            "transaction_price": "12000.00"
          }
        ]
      },
      "RevenueContractOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Contract id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "`RC-2027-000001`, per entity and year of the start date."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "The customer's id."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "The customer's code."
          },
          "party_name": {
            "type": "string",
            "title": "Party Name",
            "description": "The customer's name."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the contract is."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency it is priced and billed in; revenue is booked in the entity's functional currency (ADR-0050)."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first day."
          },
          "end_date": {
            "type": "string",
            "format": "date",
            "title": "End Date",
            "description": "The last day."
          },
          "transaction_price": {
            "type": "string",
            "title": "Transaction Price",
            "description": "Fixed consideration, net of VAT."
          },
          "right_to_consideration": {
            "type": "string",
            "title": "Right To Consideration",
            "description": "`conditional` or `unconditional`."
          },
          "right_basis": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Right Basis",
            "description": "Why the right is unconditional."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "cancelled",
              "completed",
              "draft",
              "pending_approval"
            ],
            "title": "Status",
            "description": "The status."
          },
          "plan_version": {
            "type": "integer",
            "title": "Plan Version",
            "description": "The schedule's current plan version."
          },
          "terms_digest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms Digest",
            "description": "SHA-256 of the approved terms."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved the terms."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When (UTC)."
          },
          "cancel_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancel Reason",
            "description": "Why it was cancelled."
          },
          "obligations": {
            "items": {
              "$ref": "#/components/schemas/ObligationOut"
            },
            "type": "array",
            "title": "Obligations",
            "description": "What it promises, by line."
          },
          "modifications": {
            "items": {
              "$ref": "#/components/schemas/ContractModificationOut"
            },
            "type": "array",
            "title": "Modifications",
            "description": "Changes of the active contract's terms, accounted for prospectively (ADR-0047), by plan version."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "party_id",
          "party_code",
          "party_name",
          "title",
          "currency",
          "start_date",
          "end_date",
          "transaction_price",
          "right_to_consideration",
          "right_basis",
          "status",
          "plan_version",
          "terms_digest",
          "approved_by",
          "approved_at",
          "cancel_reason",
          "obligations",
          "created_by",
          "created_at"
        ],
        "title": "RevenueContractOut",
        "examples": [
          {
            "created_at": "2026-10-04T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "end_date": "2027-12-31",
            "entity": "CH01",
            "id": "8e1f2a3b-4c5d-4e6f-9a7b-8c9d0e1f2a3b",
            "number": "RC-2027-000001",
            "obligations": [],
            "party_code": "C-CH",
            "party_id": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
            "party_name": "Zürich Kunde AG",
            "plan_version": 1,
            "right_to_consideration": "conditional",
            "start_date": "2027-01-01",
            "status": "draft",
            "title": "Platform 2027",
            "transaction_price": "12000.00"
          }
        ]
      },
      "ReverseRequest": {
        "properties": {
          "on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "On",
            "description": "Date of the reversal, ISO 8601; its period must exist and be open. Default: the date of the entry being reversed."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why it is reversed (required, at most 500 characters): appended to the description of the reversal entry and recorded in the audit trail and, when the reversal needs approval, in the approval request."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "ReverseRequest",
        "examples": [
          {
            "on": "2026-10-01",
            "reason": "Accrual released"
          }
        ]
      },
      "RoleAccounts": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "chart": {
            "type": "string",
            "title": "Chart",
            "description": "The chart template the accounts were taken from."
          },
          "added": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Added",
            "description": "The accounts added: code and role."
          },
          "present": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Present",
            "description": "Required roles the entity already had."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "chart",
          "added",
          "present"
        ],
        "title": "RoleAccounts"
      },
      "RoleAssignment": {
        "properties": {
          "role": {
            "type": "string",
            "title": "Role",
            "description": "A ready-made role's key or an own role's id (`GET /v1/roles`)."
          },
          "approver": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ApproverDeclaration"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who the person is, when the role lets them approve and their rights did not (422 `approver_declaration_missing` otherwise)."
          }
        },
        "type": "object",
        "required": [
          "role"
        ],
        "title": "RoleAssignment",
        "examples": [
          {
            "role": "ap_clerk"
          }
        ]
      },
      "RoleInput": {
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Title",
            "description": "The role's name."
          },
          "based_on": {
            "type": "string",
            "title": "Based On",
            "description": "The ready-made role it starts from (`GET /v1/roles`); what is not sent below is taken from it. Default `viewer`.",
            "default": "viewer"
          },
          "summary": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 400
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary",
            "description": "What it is for."
          },
          "scopes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scopes",
            "description": "Its rights: `read` always, and any of `draft`, `post`, `approve`, `audit`, `admin` (`admin` holds every right and opens every area)."
          },
          "areas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Areas",
            "description": "The areas of the app it opens (`ledger`, `sales`, `purchasing`, `bank`, `assets`, `close`, `reports`, `stock`, `service`: `GET /v1/roles/areas`); null: every area. Omit to take them from `based_on`."
          },
          "visibility": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "all",
                  "own",
                  "team"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Visibility",
            "description": "Which sales records its people see: `all`, `team` (their sales teams') or `own` (theirs)."
          }
        },
        "type": "object",
        "required": [
          "title"
        ],
        "title": "RoleInput",
        "examples": [
          {
            "based_on": "ap_clerk",
            "scopes": [
              "read",
              "draft",
              "post",
              "approve"
            ],
            "title": "Payables lead"
          },
          {
            "areas": [
              "service",
              "sales"
            ],
            "based_on": "support_agent",
            "title": "Customer success"
          }
        ]
      },
      "RoleOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "A ready-made role's key (`ap_clerk`, `sales_rep`, ...) or an own role's id."
          },
          "kind": {
            "type": "string",
            "enum": [
              "own",
              "ready_made"
            ],
            "title": "Kind",
            "description": "`ready_made` (the product's, unchangeable) or `own` (the organization's)."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "The role's name."
          },
          "summary": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary",
            "description": "What the role is for."
          },
          "based_on": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Based On",
            "description": "An own role: the ready-made role it was made from."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "Its rights: `read` always, and any of `draft`, `post`, `approve`, `audit`, `admin` (`admin` holds every right and opens every area)."
          },
          "areas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Areas",
            "description": "The areas of the app it opens (`ledger`, `sales`, `purchasing`, `bank`, `assets`, `close`, `reports`, `stock`, `service`: `GET /v1/roles/areas`); null: every area."
          },
          "visibility": {
            "type": "string",
            "enum": [
              "all",
              "own",
              "team"
            ],
            "title": "Visibility",
            "description": "Which sales records its people see: `all`, `team` (their sales teams') or `own` (theirs)."
          },
          "can": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Can",
            "description": "What someone with the role can do, in plain words."
          },
          "cannot": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Cannot",
            "description": "What they cannot do, in plain words."
          },
          "people": {
            "type": "integer",
            "title": "People",
            "description": "How many people of the organization have it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "title",
          "scopes",
          "areas",
          "visibility",
          "can",
          "cannot",
          "people"
        ],
        "title": "RoleOut"
      },
      "RoleUpdate": {
        "properties": {
          "title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 80,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Title",
            "description": "The role's new name."
          },
          "summary": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 400
              },
              {
                "type": "null"
              }
            ],
            "title": "Summary",
            "description": "What the role is for, in a sentence."
          },
          "scopes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scopes",
            "description": "Its rights: `read` always, and any of `draft`, `post`, `approve`, `audit`, `admin` (`admin` holds every right and opens every area)."
          },
          "areas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Areas",
            "description": "The areas of the app it opens (`ledger`, `sales`, `purchasing`, `bank`, `assets`, `close`, `reports`, `stock`, `service`: `GET /v1/roles/areas`); null: every area. Omit to keep them; send null for every area."
          },
          "visibility": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "all",
                  "own",
                  "team"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Visibility",
            "description": "Which sales records its people see: `all`, `team` (their sales teams') or `own` (theirs)."
          }
        },
        "type": "object",
        "title": "RoleUpdate",
        "examples": [
          {
            "areas": [
              "purchasing",
              "bank"
            ]
          },
          {
            "title": "AP lead"
          }
        ]
      },
      "RollForwardEffect": {
        "properties": {
          "on": {
            "type": "string",
            "title": "On",
            "description": "The month `YYYY-MM` of a profit, or the date of an equity movement."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The profit or the movement, in the functional currency."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "The average rate of the month or the rate of the date."
          },
          "effect": {
            "type": "string",
            "title": "Effect",
            "description": "`amount` x (closing rate - `rate`): what the move of the closing rate did to the reserve."
          }
        },
        "type": "object",
        "required": [
          "on",
          "amount",
          "rate",
          "effect"
        ],
        "title": "RollForwardEffect"
      },
      "RollInput": {
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "prior_year",
              "run_rate"
            ],
            "title": "Method",
            "description": "How the periods new to the horizon are filled, for an account whose lines in the version rolled from say neither: `run_rate` (the average of the last `periods` closed periods) or `prior_year` (the same period a year earlier, closed or forecast, times 1 + `growth_pct` / 100). An account whose latest line is `run_rate` or `prior_year` keeps its own method.",
            "default": "run_rate"
          },
          "periods": {
            "type": "integer",
            "maximum": 12.0,
            "minimum": 1.0,
            "title": "Periods",
            "description": "How many closed periods `run_rate` averages.",
            "default": 3
          },
          "growth_pct": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1000.0,
                "minimum": -100.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,5}|(?=[\\d.]{1,8}0*$)\\d{0,5}\\.\\d{0,2}0*$)"
              }
            ],
            "title": "Growth Pct",
            "description": "Growth in percent over the prior year, for `prior_year` (e.g. `5` for 5 %).",
            "default": "0"
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "What this version is about; empty: a note saying what was rolled."
          },
          "refresh": {
            "type": "boolean",
            "title": "Refresh",
            "description": "Project again the open periods the version rolled from projected (`run_rate`, `prior_year`, `schedule`), keeping only the lines people entered (`manual`); false carries every open period over as it was. The rolling forecast every company has rolls with it.",
            "default": false
          }
        },
        "type": "object",
        "title": "RollInput",
        "examples": [
          {
            "method": "run_rate",
            "periods": 3
          },
          {
            "growth_pct": "5",
            "method": "prior_year",
            "note": "October roll"
          }
        ]
      },
      "RollResult": {
        "properties": {
          "version": {
            "$ref": "#/components/schemas/VersionOut",
            "description": "The new draft (a person reviews and approves it)."
          },
          "rolled_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rolled From",
            "description": "The version it was rolled from: the plan's current one, else its latest."
          },
          "actuals_through": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Actuals Through",
            "description": "The last closed period, whose actuals the version holds (`YYYY-NN`); empty when no period of the year is closed yet."
          },
          "horizon_start": {
            "type": "string",
            "title": "Horizon Start",
            "description": "The first open period: where the forecast begins."
          },
          "horizon_end": {
            "type": "string",
            "title": "Horizon End",
            "description": "The last period of the horizon that exists."
          },
          "horizon_short_by": {
            "type": "integer",
            "title": "Horizon Short By",
            "description": "Periods of the horizon that have no fiscal period yet: open the next fiscal year (`POST /v1/entities/{entity}/fiscal-years`) and roll again to fill them."
          },
          "lines": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Lines",
            "description": "The new version's lines by method (`actual`, carried over ones keep theirs)."
          }
        },
        "type": "object",
        "required": [
          "version",
          "rolled_from",
          "actuals_through",
          "horizon_start",
          "horizon_end",
          "horizon_short_by",
          "lines"
        ],
        "title": "RollResult"
      },
      "RollingForecastOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its functional currency: every amount is in it."
          },
          "plan_id": {
            "type": "string",
            "format": "uuid",
            "title": "Plan Id",
            "description": "The plan named `Rolling forecast`."
          },
          "version_id": {
            "type": "string",
            "format": "uuid",
            "title": "Version Id",
            "description": "Its latest version, the last roll."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "That version's number."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "That version's status (`draft`, `submitted`, `approved`, `superseded`): a roll is a `draft` until a person approves it."
          },
          "made_at": {
            "type": "string",
            "format": "date-time",
            "title": "Made At",
            "description": "When that version was made."
          },
          "made_by_system": {
            "type": "boolean",
            "title": "Made By System",
            "description": "The system rolled it (not a person)."
          },
          "actuals_through": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Actuals Through",
            "description": "The last closed period whose actuals it holds; none before the first close."
          },
          "periods": {
            "items": {
              "$ref": "#/components/schemas/ForecastPeriod"
            },
            "type": "array",
            "title": "Periods",
            "description": "Each period of the version, in order: the year's actuals, then the forecast."
          },
          "ahead": {
            "$ref": "#/components/schemas/ForecastTotals",
            "description": "The totals of the periods not closed yet."
          },
          "periods_ahead": {
            "type": "integer",
            "title": "Periods Ahead",
            "description": "How many periods `ahead` covers."
          },
          "link": {
            "type": "string",
            "title": "Link",
            "description": "Where the app shows the plan."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "plan_id",
          "version_id",
          "version",
          "status",
          "made_at",
          "made_by_system",
          "actuals_through",
          "periods",
          "ahead",
          "periods_ahead",
          "link"
        ],
        "title": "RollingForecastOut",
        "examples": [
          {
            "actuals_through": "2026-09",
            "ahead": {
              "expenses": "198000.00",
              "net": "42000.00",
              "revenue": "240000.00"
            },
            "currency": "CHF",
            "entity": "CH01",
            "link": "/plans/6f1c2a10-4b5e-4d7a-9a3b-2c1d0e9f8a7b",
            "made_at": "2026-10-02T06:00:00Z",
            "made_by_system": true,
            "periods": [],
            "periods_ahead": 12,
            "plan_id": "6f1c2a10-4b5e-4d7a-9a3b-2c1d0e9f8a7b",
            "status": "draft",
            "version": 3,
            "version_id": "7d2e3f40-5162-4c73-8d84-9ea5fb6c7d18"
          }
        ]
      },
      "RoomRateInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1,
            "title": "Name",
            "description": "The season: `Winter season`."
          },
          "first_night": {
            "type": "string",
            "format": "date",
            "title": "First Night",
            "description": "The first night of the season."
          },
          "last_night": {
            "type": "string",
            "format": "date",
            "title": "Last Night",
            "description": "The last night of the season, included (at most a year after the first)."
          },
          "nightly_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Nightly Price",
            "description": "Net price of one room for one night."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code; omitted: the entity's functional currency. The seasons of a room type in one currency never overlap."
          }
        },
        "type": "object",
        "required": [
          "name",
          "first_night",
          "last_night",
          "nightly_price"
        ],
        "title": "RoomRateInput",
        "examples": [
          {
            "first_night": "2026-12-19",
            "last_night": "2027-03-14",
            "name": "Winter season",
            "nightly_price": "260.00"
          }
        ]
      },
      "RoomRateOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the season."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The season's name."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code."
          },
          "first_night": {
            "type": "string",
            "format": "date",
            "title": "First Night",
            "description": "First night."
          },
          "last_night": {
            "type": "string",
            "format": "date",
            "title": "Last Night",
            "description": "Last night, included."
          },
          "nightly_price": {
            "type": "string",
            "title": "Nightly Price",
            "description": "Net price of one room for one night."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who added it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "currency",
          "first_night",
          "last_night",
          "nightly_price",
          "created_by",
          "created_at"
        ],
        "title": "RoomRateOut"
      },
      "RoomTypeInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity that lets the rooms."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Product code of the room type, e.g. `DBL`; omitted: the next product number (`P-00001`)."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What it is called on invoices: `Double room`."
          },
          "rooms": {
            "type": "integer",
            "maximum": 1000.0,
            "minimum": 1.0,
            "title": "Rooms",
            "description": "How many rooms of the type there are: the rooms free each night."
          },
          "max_guests": {
            "type": "integer",
            "maximum": 50.0,
            "minimum": 1.0,
            "title": "Max Guests",
            "description": "How many guests one room sleeps (1 to 50). Default 2.",
            "default": 2
          },
          "nightly_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Nightly Price",
            "description": "Net price of one room for one night outside any season: the product's list price. A season (`POST /v1/room-types/{product_id}/rates`) or the customer's price list prices a night instead."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code of the price; omitted: the entity's functional currency."
          },
          "valid_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid From",
            "description": "The first night the price applies; omitted: today."
          },
          "rate_type": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "exempt",
                  "parking",
                  "reduced",
                  "special",
                  "standard",
                  "super_reduced",
                  "zero"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Type",
            "description": "The VAT rate type of a night; omitted: the one the entity's VAT area has for accommodation on the day (Switzerland `special` 3.8 %, Germany `reduced` 7 %), else `standard`."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name",
          "rooms",
          "nightly_price"
        ],
        "title": "RoomTypeInput",
        "examples": [
          {
            "entity": "CH01",
            "name": "Double room",
            "nightly_price": "210.00",
            "rooms": 12
          },
          {
            "code": "SGL",
            "currency": "CHF",
            "entity": "CH01",
            "max_guests": 1,
            "name": "Single room",
            "nightly_price": "160.00",
            "rooms": 8
          }
        ]
      },
      "RoomTypeOut": {
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Id of the room type's product."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Product code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Product name."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether the rooms are still let."
          },
          "rooms": {
            "type": "integer",
            "title": "Rooms",
            "description": "How many rooms of the type there are: the rooms free each night."
          },
          "max_guests": {
            "type": "integer",
            "title": "Max Guests",
            "description": "How many guests one room sleeps (1 to 50)."
          },
          "rate_type": {
            "type": "string",
            "title": "Rate Type",
            "description": "The VAT rate type of a night (the product's)."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency, of `nightly_price`."
          },
          "nightly_price": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Nightly Price",
            "description": "The list price of one night today, outside any season; null when the product has none in the currency."
          },
          "free_tonight": {
            "type": "integer",
            "title": "Free Tonight",
            "description": "Rooms not booked for tonight."
          },
          "rates": {
            "items": {
              "$ref": "#/components/schemas/RoomRateOut"
            },
            "type": "array",
            "title": "Rates",
            "description": "Its seasons, by currency and first night."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who added the room type."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "product_id",
          "entity",
          "code",
          "name",
          "active",
          "rooms",
          "max_guests",
          "rate_type",
          "currency",
          "nightly_price",
          "free_tonight",
          "rates",
          "created_by",
          "created_at"
        ],
        "title": "RoomTypeOut"
      },
      "RoomTypeUpdate": {
        "properties": {
          "rooms": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 1000.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Rooms",
            "description": "How many rooms of the type there are: the rooms free each night. Refused below what is booked on a night from today on."
          },
          "max_guests": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 50.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Max Guests",
            "description": "How many guests one room sleeps (1 to 50)."
          }
        },
        "type": "object",
        "title": "RoomTypeUpdate",
        "examples": [
          {
            "rooms": 14
          },
          {
            "max_guests": 3
          }
        ]
      },
      "RunCollection": {
        "properties": {
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "title": "Payment Id",
            "description": "Id of the receipt created."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Customer name."
          },
          "mandate_reference": {
            "type": "string",
            "title": "Mandate Reference",
            "description": "The mandate collected under."
          },
          "sequence_type": {
            "type": "string",
            "enum": [
              "FNAL",
              "FRST",
              "OOFF",
              "RCUR"
            ],
            "title": "Sequence Type",
            "description": "`RCUR` or `OOFF`."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount collected."
          },
          "documents": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Documents",
            "description": "Invoice numbers settled."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted` or `pending_approval`."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "When it waits for approval."
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "customer",
          "customer_name",
          "mandate_reference",
          "sequence_type",
          "amount",
          "documents",
          "status"
        ],
        "title": "RunCollection"
      },
      "RunEliminations": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the run."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The reporting currency."
          },
          "rules": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Rules",
            "description": "The rules the run applied."
          },
          "pending": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Pending",
            "description": "The rules of the design not applied yet."
          },
          "acquisitions": {
            "items": {
              "$ref": "#/components/schemas/Acquisition"
            },
            "type": "array",
            "title": "Acquisitions",
            "description": "Per subsidiary the capital consolidation (E4, E5, E7) with its basis."
          },
          "pairs": {
            "items": {
              "$ref": "#/components/schemas/EliminationPair"
            },
            "type": "array",
            "title": "Pairs",
            "description": "One entry per rule and pair of entities that hold anything towards each other."
          },
          "debit": {
            "type": "string",
            "title": "Debit",
            "description": "Total debit of the elimination layer, the capital rules included."
          },
          "credit": {
            "type": "string",
            "title": "Credit",
            "description": "Total credit: equal to the debit, every pair balances."
          }
        },
        "type": "object",
        "required": [
          "run",
          "currency",
          "rules",
          "pending",
          "pairs",
          "debit",
          "credit"
        ],
        "title": "RunEliminations"
      },
      "RunException": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "`rate_missing` (a rate the rate source does not publish), `unmapped_report_line` (an account on a line outside the group's vocabulary), `cta_unreconciled` (the reserve and its roll-forward differ by more than rounding), `period_open` (a period of the entity is still open), `member_not_consolidated` (a member starts after the date), `opening_position_missing` (a member is consolidated from a date after it was acquired: its investment cannot be eliminated, blocking), `acquisition_basis_incomplete`, `ownership_change_unsupported`, `investment_differs_from_cost` and `fair_value_adjustment_unsupported` (the capital consolidation cannot be computed as it should: blocking), `bargain_purchase` (a gain on a bargain purchase, to be reassessed, IFRS 3.36), `goodwill_impairment_not_tested` and `negative_goodwill_not_released` (HGB: a negative difference after equity that the group releases itself, section 309 para. 2 HGB) (warnings), `ic_difference` (two entities' intragroup balances, or income and expense, do not agree in the document currency: blocking above the group's tolerance), `ic_capitalised` (an intragroup cost sits in an asset: blocking), `ic_exchange_difference` (agreed balances differ in the reporting currency beyond the tolerance: a balance was probably not revalued), `ic_cash_in_transit` (two entities disagree only by a payment one booked and the other not yet: shown as cash in transit, a warning); a run made before the capital consolidation also has `eliminations_pending` and `cta_starts_at_zero`."
          },
          "severity": {
            "type": "string",
            "enum": [
              "blocking",
              "warning"
            ],
            "title": "Severity",
            "description": "`blocking`: the statements are incomplete or wrong and a final run could not be made; `warning`: to know, not blocking."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code of the entity concerned; null for the group."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "What it is, in English words."
          },
          "details": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Details",
            "description": "The values the words of the code name, by name (amounts as decimal strings, days as ISO dates, lists, or reasons with their own `words`, `code`, `details` and `text`): the screens word the exception as `consolidation.exception.<code>` in the person's language. Null for runs made before they were kept, and for `eliminations_pending` and `cta_starts_at_zero`."
          }
        },
        "type": "object",
        "required": [
          "code",
          "severity",
          "entity",
          "detail"
        ],
        "title": "RunException"
      },
      "RunExceptions": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the run."
          },
          "exceptions": {
            "items": {
              "$ref": "#/components/schemas/RunException"
            },
            "type": "array",
            "title": "Exceptions",
            "description": "The exceptions of the run, blocking first."
          }
        },
        "type": "object",
        "required": [
          "run",
          "exceptions"
        ],
        "title": "RunExceptions"
      },
      "RunInput": {
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The group date: a month end (ISO 8601), because the rates are the calendar months of data-vNext. The ledger is read up to this date by entry date."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "A note kept on the run."
          }
        },
        "type": "object",
        "required": [
          "as_of"
        ],
        "title": "RunInput",
        "examples": [
          {
            "as_of": "2026-09-30",
            "comment": "September close"
          }
        ]
      },
      "RunLine": {
        "properties": {
          "document": {
            "type": "string",
            "title": "Document",
            "description": "Bill id or number."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Amount to pay."
          },
          "discount": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Discount",
            "description": "Cash discount taken.",
            "default": "0"
          }
        },
        "type": "object",
        "required": [
          "document",
          "amount"
        ],
        "title": "RunLine"
      },
      "RunMember": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "role": {
            "type": "string",
            "enum": [
              "parent",
              "subsidiary"
            ],
            "title": "Role",
            "description": "The parent or a subsidiary."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Its functional currency."
          },
          "version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Version",
            "description": "The member version used; null for the parent."
          },
          "ownership_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ownership Percent",
            "description": "The share used; null for the parent."
          },
          "consolidated_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Consolidated From",
            "description": "From when it is consolidated; null for the parent."
          },
          "acquired_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquired On",
            "description": "When control was acquired; null for the parent."
          },
          "purchase_data_version": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Purchase Data Version",
            "description": "The member version whose purchase data (cost, investment account, net assets) the run used: `version`, or a later version that corrects them; null for the parent."
          },
          "acquisition_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Cost",
            "description": "The consideration used by E4; null when not stated."
          },
          "acquisition_cost_currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Acquisition Cost Currency",
            "description": "Its currency."
          },
          "net_assets_at_acquisition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net Assets At Acquisition",
            "description": "The stated fair value of the net assets at acquisition."
          },
          "investment_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Investment Account",
            "description": "The parent's account holding the investment."
          },
          "translated": {
            "type": "boolean",
            "title": "Translated",
            "description": "False when the entity could not be translated (a rate is missing): it is not in the consolidated lines and a blocking exception says why."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "role",
          "currency",
          "version",
          "ownership_percent",
          "consolidated_from",
          "translated"
        ],
        "title": "RunMember"
      },
      "RunOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the run."
          },
          "group": {
            "type": "string",
            "title": "Group",
            "description": "Code of the group."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The group date."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "The run's number for this group and date, from 1."
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "final",
              "superseded"
            ],
            "title": "Status",
            "description": "`draft` (all that can be made in this version)."
          },
          "comment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Comment",
            "description": "The note kept on the run."
          },
          "reporting_currency": {
            "type": "string",
            "title": "Reporting Currency",
            "description": "The presentation currency, fixed when the run was made."
          },
          "framework": {
            "type": "string",
            "enum": [
              "fer",
              "hgb",
              "ifrs"
            ],
            "title": "Framework",
            "description": "The framework, fixed when the run was made."
          },
          "policy": {
            "additionalProperties": true,
            "type": "object",
            "title": "Policy",
            "description": "The resolved switches of the framework (goodwill policy, how the translation reserve is presented, the statements) with the source of each: what the run was made under."
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/RunMember"
            },
            "type": "array",
            "title": "Members",
            "description": "The entities of the run and the versions used."
          },
          "complete": {
            "type": "boolean",
            "title": "Complete",
            "description": "True when no blocking exception was found: every entity is translated, the intragroup items agree and the statements are whole for the rules applied."
          },
          "blocking": {
            "type": "integer",
            "title": "Blocking",
            "description": "The number of blocking exceptions."
          },
          "warnings": {
            "type": "integer",
            "title": "Warnings",
            "description": "The number of warnings."
          },
          "eliminations_applied": {
            "type": "boolean",
            "title": "Eliminations Applied",
            "description": "True when the run eliminated intragroup items (`eliminations` names the rules); false for a run made before the eliminations existed."
          },
          "eliminations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Eliminations",
            "description": "The elimination rules the run applied: `E1` (intragroup balances), `E2` (loans), `E3` (intragroup income and expense), `E4` (the investment against the equity at acquisition, goodwill), `E5` (non-controlling interests), `E6` (dividends) and, under `amortise`, `E7` (goodwill amortisation); an earlier run names fewer."
          },
          "eliminations_pending": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Eliminations Pending",
            "description": "The rules of the design the run did not apply: empty for a current run; a run made before the capital consolidation names `E4`, `E5` and `E7`."
          },
          "inputs_digest": {
            "type": "string",
            "title": "Inputs Digest",
            "description": "SHA-256 of the canonical JSON of everything the run was computed from: the entity balances and monthly movements, the member versions and the rates."
          },
          "entity_heads": {
            "additionalProperties": true,
            "type": "object",
            "title": "Entity Heads",
            "description": "Per entity the position and hash of its ledger chain when the run was made."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made the run, as an actor object."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was made (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "group",
          "as_of",
          "version",
          "status",
          "comment",
          "reporting_currency",
          "framework",
          "policy",
          "members",
          "complete",
          "blocking",
          "warnings",
          "eliminations_applied",
          "eliminations",
          "eliminations_pending",
          "inputs_digest",
          "entity_heads",
          "created_by",
          "created_at"
        ],
        "title": "RunOut"
      },
      "RunPayment": {
        "properties": {
          "payment_id": {
            "type": "string",
            "format": "uuid",
            "title": "Payment Id",
            "description": "Id of the payment that was created."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Vendor code."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "Vendor name."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the payment."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Amount paid, in the payment currency."
          },
          "discount": {
            "type": "string",
            "title": "Discount",
            "description": "Cash discount taken on the bills of this payment."
          },
          "documents": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Documents",
            "description": "Numbers of the bills the payment settles."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, or `pending_approval` when the approval policy needs a second person."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "Id of the approval request when the payment waits for approval."
          },
          "entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Id",
            "description": "Id of the payment's journal entry."
          }
        },
        "type": "object",
        "required": [
          "payment_id",
          "vendor",
          "vendor_name",
          "currency",
          "amount",
          "discount",
          "documents",
          "status",
          "approval_id"
        ],
        "title": "RunPayment"
      },
      "RunRates": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the run."
          },
          "pinned_version": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Pinned Version",
            "description": "The dataset version the ERP was pinned to when the run was made, if any."
          },
          "rates": {
            "items": {
              "$ref": "#/components/schemas/RateUse"
            },
            "type": "array",
            "title": "Rates",
            "description": "Every rate the run used."
          }
        },
        "type": "object",
        "required": [
          "run",
          "pinned_version",
          "rates"
        ],
        "title": "RunRates"
      },
      "RunSummary": {
        "properties": {
          "run_id": {
            "type": "string",
            "format": "uuid",
            "title": "Run Id",
            "description": "Id of the recorded run (one per kind and period)."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`depreciation`, `fx_revaluation` or `deferred_tax`."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period as `YYYY-NN`, e.g. `2026-09`."
          },
          "items": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Items",
            "description": "What was processed. Depreciation: `asset`, `amount`, `dataset_version`. FX revaluation: `item` (document number or bank account), `currency`, `open`, `carrying`, `closing`, `difference` (closing less carrying), `result` (what the entry books to profit and loss: a gain positive, a loss negative) and, on a run again, `booked` (what the earlier entries booked). Deferred tax: the per-asset differences of the book (see `DifferenceLine`)."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Depreciation: the amount posted. FX revaluation: the result posted (a gain positive, a loss negative). Deferred tax: the movement posted. In the entity's functional currency."
          },
          "submit": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The posted entry with the approval policy decision (allow, require_approval, deny); null when there was nothing to post."
          }
        },
        "type": "object",
        "required": [
          "run_id",
          "kind",
          "period",
          "items",
          "total",
          "submit"
        ],
        "title": "RunSummary"
      },
      "SalesActivityReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "date_from": {
            "type": "string",
            "format": "date",
            "title": "Date From",
            "description": "First day counted."
          },
          "date_to": {
            "type": "string",
            "format": "date",
            "title": "Date To",
            "description": "Last day counted."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/ActivityRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "Per person (or agent), the busiest first."
          },
          "total": {
            "$ref": "#/components/schemas/ActivityRow",
            "description": "Everyone."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "date_from",
          "date_to",
          "rows",
          "total"
        ],
        "title": "SalesActivityReport",
        "examples": [
          {
            "date_from": "2026-10-01",
            "date_to": "2026-10-23",
            "entity": "CH01",
            "rows": [],
            "total": {
              "agent": false,
              "calls": 14,
              "emails": 22,
              "key": "total",
              "meetings": 5,
              "name": "",
              "notes": 3,
              "open_tasks": 6,
              "overdue_tasks": 2,
              "stage_changes": 11,
              "tasks_done": 7,
              "tasks_set": 9
            }
          }
        ]
      },
      "SalesDispatchOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the hand-over."
          },
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "portal",
              "post",
              "system_email"
            ],
            "title": "Channel",
            "description": "`system_email` (this server sent it) or what a person recorded."
          },
          "handed_over_on": {
            "type": "string",
            "format": "date",
            "title": "Handed Over On",
            "description": "The day it was handed over."
          },
          "recipients": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Recipients",
            "description": "To whom."
          },
          "subject": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subject",
            "description": "Subject of the e-mail; null for a recorded one."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "The PDF handed over."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of that PDF, hex."
          },
          "sent_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Sent By",
            "description": "Who: type, id and name."
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "title": "Sent At",
            "description": "When it was sent or recorded (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "channel",
          "handed_over_on",
          "recipients",
          "subject",
          "filename",
          "sha256",
          "sent_by",
          "sent_at"
        ],
        "title": "SalesDispatchOut"
      },
      "SalesDocumentCard": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the quote or order."
          },
          "kind": {
            "type": "string",
            "enum": [
              "order",
              "quote"
            ],
            "title": "Kind",
            "description": "`quote` or `order`."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "`QT-2026-000001` or `SO-2026-000001`, per entity and year."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "A quote is `draft`, `sent`, `expired` (draft or sent, and its `valid_until` has passed), `accepted`, `declined` or `cancelled`. An order is `draft`, `open`, `partially_invoiced`, `invoiced`, `closed` (for the rest, with a reason) or `cancelled`."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Name of the customer."
          },
          "customer_id": {
            "type": "string",
            "format": "uuid",
            "title": "Customer Id",
            "description": "Id of the customer."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Day of the quote or order."
          },
          "valid_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid Until",
            "description": "Quotes: last day to accept; null on orders."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's reference; null if none."
          },
          "opportunity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Id",
            "description": "The deal it is for; null if none."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "The document discount in percent; null for an amount or none."
          },
          "discount_amount": {
            "type": "string",
            "title": "Discount Amount",
            "description": "The document discount in money; 0 for none.",
            "default": "0.00"
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Net total, after all discounts."
          },
          "tax_total": {
            "type": "string",
            "title": "Tax Total",
            "description": "VAT, as the invoice would determine it on the day."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total including VAT."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was created (UTC)."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "Raised on every change; the ETag names it."
          },
          "revision": {
            "type": "integer",
            "title": "Revision",
            "description": "Quotes: the version, from 1; changing a sent quote begins the next (it is a draft until sent again). Orders: 1.",
            "default": 1
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "payment_terms_days": {
            "type": "integer",
            "title": "Payment Terms Days",
            "description": "Payment terms in days."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Free text printed under the lines."
          },
          "legal_notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Legal Notes",
            "description": "Remarks the VAT treatment of the lines requires."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why it was declined, cancelled or closed for the rest; null otherwise."
          },
          "decided_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided By",
            "description": "Who accepted, declined, cancelled or closed it; null otherwise."
          },
          "decided_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided At",
            "description": "When (UTC); null otherwise."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it (`type`, `id`, `name`)."
          },
          "opportunity_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Number",
            "description": "The number of the deal it is for; null if none."
          },
          "quote": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SalesLinkOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "Of an order: the quote it was made from."
          },
          "order": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SalesLinkOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "Of an accepted quote: the order it became."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/SalesLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines."
          },
          "invoices": {
            "items": {
              "$ref": "#/components/schemas/OrderInvoiceOut"
            },
            "type": "array",
            "title": "Invoices",
            "description": "Of an order: the invoices made from it, oldest first."
          },
          "invoiced_net": {
            "type": "string",
            "title": "Invoiced Net",
            "description": "Of an order: the net invoiced on invoices that are not void or rejected.",
            "default": "0.00"
          },
          "dispatches": {
            "items": {
              "$ref": "#/components/schemas/SalesDispatchOut"
            },
            "type": "array",
            "title": "Dispatches",
            "description": "Hand-overs, oldest first."
          },
          "sending_configured": {
            "type": "boolean",
            "title": "Sending Configured",
            "description": "Whether this server can e-mail it (a mail server, and not a test copy)."
          },
          "suggested_recipient": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Suggested Recipient",
            "description": "Where an e-mail goes without addresses given; null when the customer has none."
          },
          "online": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/QuoteOnlineCard"
              },
              {
                "type": "null"
              }
            ],
            "description": "Of a quote: the versions handed over, the links given to answer it online and the customer's answer there (ADR-0088); null on an order."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "number",
          "status",
          "customer",
          "customer_name",
          "customer_id",
          "currency",
          "document_date",
          "valid_until",
          "customer_reference",
          "net_total",
          "tax_total",
          "total",
          "created_at",
          "version",
          "entity",
          "payment_terms_days",
          "notes",
          "legal_notes",
          "reason",
          "decided_by",
          "decided_at",
          "created_by",
          "quote",
          "order",
          "lines",
          "dispatches",
          "sending_configured",
          "suggested_recipient"
        ],
        "title": "SalesDocumentCard"
      },
      "SalesDocumentInput": {
        "properties": {
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Code (or id) of an active customer of the entity."
          },
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "Day of the quote or order (ISO 8601); default today where the company is."
          },
          "valid_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid Until",
            "description": "Quotes: the last day the customer may accept it, not before the quote's day; default 30 days after it. Orders take none."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code; default the customer's."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's reference, e.g. its request or purchase order number; printed and carried to the invoice as its order reference."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Payment terms in days; default the customer's."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Printed under the lines."
          },
          "opportunity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Id",
            "description": "The deal it is for (`GET /v1/opportunities`): one of the same customer, not lost. It never changes, and an order made from the quote is for the same deal."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/SalesLineInput"
            },
            "type": "array",
            "maxItems": 200,
            "minItems": 1,
            "title": "Lines",
            "description": "The lines."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "A discount on the whole document in percent of the lines after their own discounts; split over the lines, so the VAT of each rate goes down by its share. Give this or `discount_amount`, not both."
          },
          "discount_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Amount",
            "description": "A discount on the whole document as an amount, split over the lines like `discount_percent`; an invoice of part of an order takes its part of it."
          }
        },
        "type": "object",
        "required": [
          "customer",
          "lines"
        ],
        "title": "SalesDocumentInput",
        "examples": [
          {
            "customer": "C-DE",
            "customer_reference": "RFQ-2026-118",
            "document_date": "2026-10-11",
            "lines": [
              {
                "description": "Consulting, senior",
                "product": "CONSULT",
                "quantity": "8",
                "unit_price": "180.00"
              },
              {
                "description": "Travel, flat rate",
                "quantity": "1",
                "unit_price": "450.00"
              }
            ],
            "valid_until": "2026-11-10"
          }
        ]
      },
      "SalesDocumentOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the quote or order."
          },
          "kind": {
            "type": "string",
            "enum": [
              "order",
              "quote"
            ],
            "title": "Kind",
            "description": "`quote` or `order`."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "`QT-2026-000001` or `SO-2026-000001`, per entity and year."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "A quote is `draft`, `sent`, `expired` (draft or sent, and its `valid_until` has passed), `accepted`, `declined` or `cancelled`. An order is `draft`, `open`, `partially_invoiced`, `invoiced`, `closed` (for the rest, with a reason) or `cancelled`."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Name of the customer."
          },
          "customer_id": {
            "type": "string",
            "format": "uuid",
            "title": "Customer Id",
            "description": "Id of the customer."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Day of the quote or order."
          },
          "valid_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid Until",
            "description": "Quotes: last day to accept; null on orders."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's reference; null if none."
          },
          "opportunity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Id",
            "description": "The deal it is for; null if none."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "The document discount in percent; null for an amount or none."
          },
          "discount_amount": {
            "type": "string",
            "title": "Discount Amount",
            "description": "The document discount in money; 0 for none.",
            "default": "0.00"
          },
          "net_total": {
            "type": "string",
            "title": "Net Total",
            "description": "Net total, after all discounts."
          },
          "tax_total": {
            "type": "string",
            "title": "Tax Total",
            "description": "VAT, as the invoice would determine it on the day."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total including VAT."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was created (UTC)."
          },
          "version": {
            "type": "integer",
            "title": "Version",
            "description": "Raised on every change; the ETag names it."
          },
          "revision": {
            "type": "integer",
            "title": "Revision",
            "description": "Quotes: the version, from 1; changing a sent quote begins the next (it is a draft until sent again). Orders: 1.",
            "default": 1
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "number",
          "status",
          "customer",
          "customer_name",
          "customer_id",
          "currency",
          "document_date",
          "valid_until",
          "customer_reference",
          "net_total",
          "tax_total",
          "total",
          "created_at",
          "version"
        ],
        "title": "SalesDocumentOut"
      },
      "SalesDocumentUpdate": {
        "properties": {
          "customer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer",
            "description": "Code (or id) of an active customer."
          },
          "document_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Date",
            "description": "New day of the document."
          },
          "valid_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid Until",
            "description": "Quotes: new last day."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code."
          },
          "customer_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer Reference",
            "description": "The customer's reference; null clears it."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Payment terms in days, 0 to 365."
          },
          "notes": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Notes",
            "description": "Printed under the lines; null clears it."
          },
          "lines": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/SalesLineInput"
                },
                "type": "array",
                "maxItems": 200,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines",
            "description": "Replaces every line."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "A document discount in percent; replaces any. null removes it."
          },
          "discount_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Amount",
            "description": "A document discount as an amount; replaces any. null removes it."
          }
        },
        "type": "object",
        "title": "SalesDocumentUpdate",
        "description": "Changes to a draft (a sent quote goes back to draft and is sent again). Omitted fields keep\ntheir value; ``lines`` replaces every line.",
        "examples": [
          {
            "lines": [
              {
                "description": "Consulting, senior",
                "product": "CONSULT",
                "quantity": "8",
                "unit_price": "180.00"
              },
              {
                "description": "Travel, flat rate",
                "quantity": "1",
                "unit_price": "450.00"
              }
            ],
            "valid_until": "2026-11-30"
          }
        ]
      },
      "SalesLineInput": {
        "properties": {
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "What is offered; default the product's name (required on a line without a product)."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Quantity",
            "description": "Quantity, a decimal string greater than 0.",
            "default": "1"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price",
            "description": "Net unit price in the document's currency; default the customer's price from its price list, else the product's list price on the document's day (required on a line without a product; `422` `product_unpriced` when the product has no price)."
          },
          "product": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product",
            "description": "Code (or id) of an active product of the entity (`GET /v1/products`): the line takes its name, price, supply and rate type unless it gives its own, and the invoice its revenue account."
          },
          "supply_type": {
            "type": "string",
            "enum": [
              "electronic_services",
              "goods",
              "services"
            ],
            "title": "Supply Type",
            "description": "`goods`, `services` (default) or `electronic_services`.",
            "default": "services"
          },
          "rate_type": {
            "type": "string",
            "enum": [
              "exempt",
              "parking",
              "reduced",
              "special",
              "standard",
              "super_reduced",
              "zero"
            ],
            "title": "Rate Type",
            "description": "Which VAT rate applies; default `standard`.",
            "default": "standard"
          },
          "tax_category": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Category",
            "description": "One of the categories of the rate (`GET /v1/entities/{entity}/vat-rate-types`), e.g. `books`: it chooses the rate where the rate type has several (France reduced: 5.5 % or 10 %) and names the kind of an exempt supply (`insurance`). Omit for none."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "A discount on the line in percent (above 0, at most 100); carried to the order and its invoices. Give this or `discount_amount`, not both."
          },
          "discount_amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Amount",
            "description": "A discount on the line as an amount off quantity times unit price; an invoice of part of the line takes its part of it."
          }
        },
        "type": "object",
        "title": "SalesLineInput"
      },
      "SalesLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the line."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Position, from 1."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What is offered or ordered."
          },
          "product_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product Id",
            "description": "Id of the product; null for a free line."
          },
          "product": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Product",
            "description": "Code of the product; null for none."
          },
          "supply_type": {
            "type": "string",
            "title": "Supply Type",
            "description": "`goods`, `services` or `electronic_services`."
          },
          "rate_type": {
            "type": "string",
            "title": "Rate Type",
            "description": "The VAT rate type."
          },
          "tax_category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Category",
            "description": "Named tax category; null when none."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net unit price."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Discount Percent",
            "description": "The line discount in percent; null for an amount or none."
          },
          "discount_amount": {
            "type": "string",
            "title": "Discount Amount",
            "description": "The line discount in money; 0 for none.",
            "default": "0.00"
          },
          "document_discount_amount": {
            "type": "string",
            "title": "Document Discount Amount",
            "description": "The line's share of the document discount.",
            "default": "0.00"
          },
          "net_amount": {
            "type": "string",
            "title": "Net Amount",
            "description": "Quantity times unit price, rounded, less the line discount and its share of the document discount."
          },
          "tax_rate": {
            "type": "string",
            "title": "Tax Rate",
            "description": "VAT rate in percent, as the invoice would charge it."
          },
          "tax_amount": {
            "type": "string",
            "title": "Tax Amount",
            "description": "VAT of the line."
          },
          "closed_quantity": {
            "type": "string",
            "title": "Closed Quantity",
            "description": "Of an order closed for the rest: what will not be invoiced any more."
          },
          "invoiced_quantity": {
            "type": "string",
            "title": "Invoiced Quantity",
            "description": "Of an order: the quantity on its invoices that are not void or rejected (drafts too).",
            "default": "0"
          },
          "left_quantity": {
            "type": "string",
            "title": "Left Quantity",
            "description": "Of an open order: what is left to invoice (ordered, less closed, less invoiced); 0 otherwise.",
            "default": "0"
          },
          "shipped_quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Shipped Quantity",
            "description": "Of an order line of a stock item: what left on delivery notes (drafts too) and with invoices that ship it; null for other lines."
          },
          "left_to_ship_quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Left To Ship Quantity",
            "description": "Of an open order's line of a stock item: what is left to ship (ordered, less closed, less shipped); 0 on an order no longer open; null for other lines."
          }
        },
        "type": "object",
        "required": [
          "id",
          "line_no",
          "description",
          "product_id",
          "supply_type",
          "rate_type",
          "tax_category",
          "quantity",
          "unit_price",
          "net_amount",
          "tax_rate",
          "tax_amount",
          "closed_quantity"
        ],
        "title": "SalesLineOut"
      },
      "SalesLinkOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the linked quote or order."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Its status."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status"
        ],
        "title": "SalesLinkOut"
      },
      "SalesMarkSentInput": {
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "other",
              "portal",
              "post"
            ],
            "title": "Channel",
            "description": "`email`, `post`, `portal` or `other`."
          },
          "recipient": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Recipient",
            "description": "Who got it."
          },
          "handed_over_on": {
            "type": "string",
            "format": "date",
            "title": "Handed Over On",
            "description": "The day it was handed over: not before the document's day, not after today."
          }
        },
        "type": "object",
        "required": [
          "channel",
          "recipient",
          "handed_over_on"
        ],
        "title": "SalesMarkSentInput",
        "examples": [
          {
            "channel": "post",
            "handed_over_on": "2026-10-12",
            "recipient": "Berlin GmbH"
          }
        ]
      },
      "SalesSendInput": {
        "properties": {
          "to": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 5,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "To",
            "description": "Addresses of the customer (as for an invoice); omitted: its billing address."
          },
          "message": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "A text placed before the standard text."
          }
        },
        "type": "object",
        "title": "SalesSendInput",
        "examples": [
          {},
          {
            "to": [
              "einkauf@berlin-gmbh.example"
            ]
          }
        ]
      },
      "SalesTaxAreaInput": {
        "properties": {
          "state": {
            "type": "string",
            "pattern": "^US-[A-Z]{2}$",
            "title": "State",
            "description": "The state, e.g. `US-CA`."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z0-9][A-Z0-9-]{0,39}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "A code of its own, e.g. `LOS-ANGELES`. Omitted: made from the name (capitals, digits and hyphens, with `-2` when taken)."
          },
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name",
            "description": "Its name."
          },
          "jurisdictions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "maxItems": 20,
            "title": "Jurisdictions",
            "description": "The codes of its local jurisdictions (county, city, district) in the same state; the state's own rate always applies on top."
          }
        },
        "type": "object",
        "required": [
          "state",
          "name",
          "jurisdictions"
        ],
        "title": "SalesTaxAreaInput",
        "examples": [
          {
            "code": "LOS-ANGELES",
            "jurisdictions": [
              "CA-LA-DIST"
            ],
            "name": "City of Los Angeles",
            "state": "US-CA"
          }
        ]
      },
      "SalesTaxAreaOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the area."
          },
          "state": {
            "type": "string",
            "title": "State",
            "description": "The state."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Its code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          },
          "jurisdictions": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Jurisdictions",
            "description": "The codes of its local jurisdictions."
          },
          "combined_rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Combined Rate",
            "description": "State plus local rates in force on `on`; null when one has no rate yet."
          }
        },
        "type": "object",
        "required": [
          "id",
          "state",
          "code",
          "name",
          "jurisdictions",
          "combined_rate"
        ],
        "title": "SalesTaxAreaOut"
      },
      "SalesTaxAreaUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New name."
          },
          "jurisdictions": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 20
              },
              {
                "type": "null"
              }
            ],
            "title": "Jurisdictions",
            "description": "The codes of its local jurisdictions."
          }
        },
        "type": "object",
        "title": "SalesTaxAreaUpdate",
        "examples": [
          {
            "jurisdictions": [
              "CA-LA-DIST"
            ]
          }
        ]
      },
      "SalesTaxCategoryRuleInput": {
        "properties": {
          "state": {
            "type": "string",
            "pattern": "^US-[A-Z]{2}$",
            "title": "State",
            "description": "The state."
          },
          "category": {
            "type": "string",
            "enum": [
              "clothing",
              "digital_goods",
              "general",
              "groceries",
              "medical",
              "professional_services",
              "saas"
            ],
            "title": "Category",
            "description": "The product category."
          },
          "taxable_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,3}|(?=[\\d.]{1,6}0*$)\\d{0,3}\\.\\d{0,2}0*$)"
              }
            ],
            "title": "Taxable Percent",
            "description": "How much of the price the state taxes: `0` exempt, `100` fully taxed, `80` for Texas data processing."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 300
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why, e.g. the statute."
          }
        },
        "type": "object",
        "required": [
          "state",
          "category",
          "taxable_percent"
        ],
        "title": "SalesTaxCategoryRuleInput",
        "examples": [
          {
            "category": "saas",
            "state": "US-TX",
            "taxable_percent": "80"
          }
        ]
      },
      "SalesTaxCategoryRuleOut": {
        "properties": {
          "state": {
            "type": "string",
            "title": "State",
            "description": "The state."
          },
          "category": {
            "type": "string",
            "enum": [
              "clothing",
              "digital_goods",
              "general",
              "groceries",
              "medical",
              "professional_services",
              "saas"
            ],
            "title": "Category",
            "description": "The product category."
          },
          "taxable_percent": {
            "type": "string",
            "title": "Taxable Percent",
            "description": "How much of the price is taxed, in percent."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why, or null."
          }
        },
        "type": "object",
        "required": [
          "state",
          "category",
          "taxable_percent",
          "note"
        ],
        "title": "SalesTaxCategoryRuleOut"
      },
      "SalesTaxCustomerInput": {
        "properties": {
          "area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Area",
            "description": "The tax area of the customer's location (its code), or null."
          },
          "exemption_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 60
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption Number",
            "description": "The exemption certificate's number, or null."
          },
          "exemption_reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "government",
                  "manufacturing",
                  "nonprofit",
                  "other",
                  "resale"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption Reason",
            "description": "Why it is exempt: `resale`, `nonprofit`, `government`, `manufacturing` or `other`; required with a number."
          },
          "exempt_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exempt From",
            "description": "The first day the certificate is valid; with a number, the day it is recorded when omitted."
          },
          "exempt_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exempt Until",
            "description": "The certificate's expiry; null when it does not expire."
          },
          "exempt_states": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exempt States",
            "description": "The states the certificate is valid in (e.g. a multistate certificate); with a number, the customer's own state when omitted."
          }
        },
        "type": "object",
        "title": "SalesTaxCustomerInput",
        "examples": [
          {
            "area": "LOS-ANGELES",
            "exempt_from": "2026-01-01",
            "exempt_states": [
              "US-CA"
            ],
            "exempt_until": "2027-12-31",
            "exemption_number": "SR-FH-123456",
            "exemption_reason": "resale"
          }
        ]
      },
      "SalesTaxCustomerOut": {
        "properties": {
          "party": {
            "type": "string",
            "title": "Party",
            "description": "The customer's code."
          },
          "state": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "State",
            "description": "The customer's state, e.g. `US-CA`, or null."
          },
          "area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Area",
            "description": "Its tax area's code, or null."
          },
          "area_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Area Name",
            "description": "Its tax area's name, or null."
          },
          "exemption_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption Number",
            "description": "Its exemption certificate's number."
          },
          "exemption_reason": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "government",
                  "manufacturing",
                  "nonprofit",
                  "other",
                  "resale"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption Reason",
            "description": "Why it is exempt."
          },
          "exempt_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exempt From",
            "description": "The first day the certificate is valid."
          },
          "exempt_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exempt Until",
            "description": "When the certificate expires."
          },
          "exempt_states": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Exempt States",
            "description": "The states the certificate is valid in."
          },
          "exempt_today": {
            "type": "boolean",
            "title": "Exempt Today",
            "description": "True when the certificate is valid today in the customer's state."
          }
        },
        "type": "object",
        "required": [
          "party",
          "state",
          "area",
          "area_name",
          "exemption_number",
          "exemption_reason",
          "exempt_from",
          "exempt_until",
          "exempt_states",
          "exempt_today"
        ],
        "title": "SalesTaxCustomerOut"
      },
      "SalesTaxFigures": {
        "properties": {
          "gross_sales": {
            "type": "string",
            "title": "Gross Sales",
            "description": "All sales to customers in the state, net of credit notes and discounts."
          },
          "exempt_customer_sales": {
            "type": "string",
            "title": "Exempt Customer Sales",
            "description": "Sales to customers with a valid exemption certificate."
          },
          "exempt_product_sales": {
            "type": "string",
            "title": "Exempt Product Sales",
            "description": "Sales of products, or parts of their price, the state does not tax."
          },
          "taxable_sales": {
            "type": "string",
            "title": "Taxable Sales",
            "description": "Gross sales less the exempt ones."
          },
          "tax": {
            "type": "string",
            "title": "Tax",
            "description": "The sales tax collected."
          },
          "use_tax_purchases": {
            "type": "string",
            "title": "Use Tax Purchases",
            "description": "Purchases the vendor charged no sales tax on, used in the state: the use tax base."
          },
          "use_tax": {
            "type": "string",
            "title": "Use Tax",
            "description": "The use tax self-assessed on them."
          },
          "tax_due": {
            "type": "string",
            "title": "Tax Due",
            "description": "`tax` plus `use_tax`: what is due to the state."
          },
          "jurisdictions": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxJurisdictionLine"
            },
            "type": "array",
            "title": "Jurisdictions",
            "description": "The tax collected by jurisdiction and rate, state first."
          }
        },
        "type": "object",
        "required": [
          "gross_sales",
          "exempt_customer_sales",
          "exempt_product_sales",
          "taxable_sales",
          "tax",
          "use_tax_purchases",
          "use_tax",
          "tax_due",
          "jurisdictions"
        ],
        "title": "SalesTaxFigures",
        "description": "What a state's return asks for, from the posted journal lines of the period."
      },
      "SalesTaxFileInput": {
        "properties": {
          "state": {
            "type": "string",
            "pattern": "^US-[A-Z]{2}$",
            "title": "State",
            "description": "The state, e.g. `US-TX`."
          },
          "period": {
            "type": "string",
            "pattern": "^\\d{4}(-(0[1-9]|1[0-2]|Q[1-4]))?$",
            "title": "Period",
            "description": "The period by the registration's frequency: `2026-08`, `2026-Q3`, `2026`."
          },
          "filed_on": {
            "type": "string",
            "format": "date",
            "title": "Filed On",
            "description": "The day it was filed with the state: after the period, not in the future."
          },
          "confirmation": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Confirmation",
            "description": "The state's confirmation number. Optional."
          }
        },
        "type": "object",
        "required": [
          "state",
          "period",
          "filed_on"
        ],
        "title": "SalesTaxFileInput",
        "examples": [
          {
            "confirmation": "TX-0918-55821",
            "filed_on": "2026-09-18",
            "period": "2026-08",
            "state": "US-TX"
          }
        ]
      },
      "SalesTaxFilingOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the filed return."
          },
          "filed_on": {
            "type": "string",
            "format": "date",
            "title": "Filed On",
            "description": "The day it was filed with the state."
          },
          "confirmation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Confirmation",
            "description": "The state's confirmation number, or null."
          },
          "filed_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Filed By",
            "description": "Who recorded the filing (type and id)."
          },
          "filed_at": {
            "type": "string",
            "format": "date-time",
            "title": "Filed At",
            "description": "When it was recorded (UTC)."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved the filing (a second person), or null while awaiting approval."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When it was approved (UTC), or null."
          },
          "figures": {
            "$ref": "#/components/schemas/SalesTaxFigures",
            "description": "The figures as filed."
          },
          "tax_due": {
            "type": "string",
            "title": "Tax Due",
            "description": "The tax filed: what the payments must cover."
          },
          "paid_amount": {
            "type": "string",
            "title": "Paid Amount",
            "description": "What the linked payments cover."
          },
          "payment_difference": {
            "type": "string",
            "title": "Payment Difference",
            "description": "`tax_due` minus `paid_amount`: what is still to pay; negative when more."
          },
          "payments": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxPaymentOut"
            },
            "type": "array",
            "title": "Payments",
            "description": "The linked payments, oldest first."
          },
          "test_copy": {
            "type": "boolean",
            "title": "Test Copy",
            "description": "True in a test copy: a record only, nothing is filed."
          }
        },
        "type": "object",
        "required": [
          "id",
          "filed_on",
          "confirmation",
          "filed_by",
          "filed_at",
          "approved_by",
          "approved_at",
          "figures",
          "tax_due",
          "paid_amount",
          "payment_difference",
          "payments",
          "test_copy"
        ],
        "title": "SalesTaxFilingOut"
      },
      "SalesTaxJurisdictionInput": {
        "properties": {
          "state": {
            "type": "string",
            "pattern": "^US-[A-Z]{2}$",
            "title": "State",
            "description": "The state it lies in, e.g. `US-CA`."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z0-9][A-Z0-9-]{0,39}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "A code of its own, e.g. `CA-LA-DIST`. Omitted: made from the name (capitals, digits and hyphens, with `-2` when taken)."
          },
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name",
            "description": "Its name."
          },
          "level": {
            "type": "string",
            "enum": [
              "city",
              "county",
              "district"
            ],
            "title": "Level",
            "description": "`county`, `city` or `district`."
          },
          "rate": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,3}|(?=[\\d.]{1,8}0*$)\\d{0,3}\\.\\d{0,4}0*$)"
              }
            ],
            "title": "Rate",
            "description": "Its rate in percent."
          },
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day of the rate."
          }
        },
        "type": "object",
        "required": [
          "state",
          "name",
          "level",
          "rate",
          "valid_from"
        ],
        "title": "SalesTaxJurisdictionInput",
        "examples": [
          {
            "code": "CA-LA-DIST",
            "level": "district",
            "name": "Los Angeles County district taxes",
            "rate": "2.5",
            "state": "US-CA",
            "valid_from": "2025-04-01"
          }
        ]
      },
      "SalesTaxJurisdictionLine": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The jurisdiction's code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          },
          "level": {
            "type": "string",
            "title": "Level",
            "description": "`state`, `county`, `city` or `district`."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "The rate charged, in percent."
          },
          "taxable": {
            "type": "string",
            "title": "Taxable",
            "description": "The taxable sales it was charged on."
          },
          "tax": {
            "type": "string",
            "title": "Tax",
            "description": "The tax collected for it."
          },
          "purchases": {
            "type": "string",
            "title": "Purchases",
            "description": "The purchases use tax was self-assessed on for it."
          },
          "use_tax": {
            "type": "string",
            "title": "Use Tax",
            "description": "The use tax self-assessed for it."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "level",
          "rate",
          "taxable",
          "tax",
          "purchases",
          "use_tax"
        ],
        "title": "SalesTaxJurisdictionLine"
      },
      "SalesTaxJurisdictionOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the jurisdiction."
          },
          "state": {
            "type": "string",
            "title": "State",
            "description": "The state it lies in."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Its code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          },
          "level": {
            "type": "string",
            "enum": [
              "city",
              "county",
              "district",
              "state"
            ],
            "title": "Level",
            "description": "`state`, `county`, `city` or `district`."
          },
          "rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate",
            "description": "The rate in force on `on`, or null if none yet."
          },
          "rates": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxRateOut"
            },
            "type": "array",
            "title": "Rates",
            "description": "Every rate, oldest first."
          }
        },
        "type": "object",
        "required": [
          "id",
          "state",
          "code",
          "name",
          "level",
          "rate",
          "rates"
        ],
        "title": "SalesTaxJurisdictionOut"
      },
      "SalesTaxPaymentCandidate": {
        "properties": {
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "Id of the posted entry."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Its number."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "Its date."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Its description."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Its source, such as `bank` or `manual`."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What it debits to the state's account."
          }
        },
        "type": "object",
        "required": [
          "journal_entry_id",
          "entry_number",
          "entry_date",
          "description",
          "source",
          "amount"
        ],
        "title": "SalesTaxPaymentCandidate"
      },
      "SalesTaxPaymentInput": {
        "properties": {
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "The posted entry that paid the state: of the return's company, dated after the period, with a debit on the state's account (`GET .../payment-candidates`)."
          }
        },
        "type": "object",
        "required": [
          "journal_entry_id"
        ],
        "title": "SalesTaxPaymentInput",
        "examples": [
          {
            "journal_entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        ]
      },
      "SalesTaxPaymentOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the link (the `{payment_id}` to unlink it)."
          },
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "Id of the posted entry that paid."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Number of that entry."
          },
          "paid_on": {
            "type": "string",
            "format": "date",
            "title": "Paid On",
            "description": "The entry's date (ISO 8601 date)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What it debited to the state's account."
          },
          "linked_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Linked By",
            "description": "Who linked it (type and id)."
          },
          "linked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Linked At",
            "description": "When it was linked (ISO 8601 timestamp, UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "journal_entry_id",
          "entry_number",
          "paid_on",
          "amount",
          "linked_by",
          "linked_at"
        ],
        "title": "SalesTaxPaymentOut"
      },
      "SalesTaxPeriodRow": {
        "properties": {
          "state": {
            "type": "string",
            "title": "State",
            "description": "The state."
          },
          "state_name": {
            "type": "string",
            "title": "State Name",
            "description": "Its name."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "`2026-08`, `2026-Q3` or `2026`."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day."
          },
          "due_on": {
            "type": "string",
            "format": "date",
            "title": "Due On",
            "description": "The day the return is due with the state."
          },
          "status": {
            "type": "string",
            "enum": [
              "awaiting_approval",
              "due_soon",
              "filed",
              "open",
              "overdue",
              "paid",
              "to_file"
            ],
            "title": "Status",
            "description": "`open` (the period has not ended), `to_file`, `due_soon` (due within 10 days), `overdue` (not recorded as filed by its due day), `awaiting_approval` (recorded as filed, not approved by a second person yet), `filed` or `paid`."
          },
          "tax": {
            "type": "string",
            "title": "Tax",
            "description": "The tax due for the period (sales and use tax), from the ledger now."
          },
          "tax_due": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Due",
            "description": "The tax filed, or null when not filed."
          },
          "filed_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Filed On",
            "description": "The day it was filed, or null."
          },
          "return_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Return Id",
            "description": "Id of the filed return, or null."
          }
        },
        "type": "object",
        "required": [
          "state",
          "state_name",
          "period",
          "start",
          "end",
          "due_on",
          "status",
          "tax",
          "tax_due",
          "filed_on",
          "return_id"
        ],
        "title": "SalesTaxPeriodRow"
      },
      "SalesTaxPeriodsOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "year": {
            "type": "integer",
            "title": "Year",
            "description": "The calendar year."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency of the amounts."
          },
          "periods": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxPeriodRow"
            },
            "type": "array",
            "title": "Periods",
            "description": "By state, then period."
          },
          "unregistered": {
            "items": {
              "$ref": "#/components/schemas/UnregisteredStateRow"
            },
            "type": "array",
            "title": "Unregistered",
            "description": "Sales of the year into states the company is not registered in: what economic nexus is measured on."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "year",
          "currency",
          "periods",
          "unregistered"
        ],
        "title": "SalesTaxPeriodsOut"
      },
      "SalesTaxProductInput": {
        "properties": {
          "category": {
            "type": "string",
            "enum": [
              "clothing",
              "digital_goods",
              "general",
              "groceries",
              "medical",
              "professional_services",
              "saas"
            ],
            "title": "Category",
            "description": "The product's sales tax category."
          }
        },
        "type": "object",
        "required": [
          "category"
        ],
        "title": "SalesTaxProductInput",
        "examples": [
          {
            "category": "saas"
          }
        ]
      },
      "SalesTaxProductOut": {
        "properties": {
          "product": {
            "type": "string",
            "title": "Product",
            "description": "The product's code."
          },
          "category": {
            "type": "string",
            "enum": [
              "clothing",
              "digital_goods",
              "general",
              "groceries",
              "medical",
              "professional_services",
              "saas"
            ],
            "title": "Category",
            "description": "Its sales tax category (`general` when not set)."
          }
        },
        "type": "object",
        "required": [
          "product",
          "category"
        ],
        "title": "SalesTaxProductOut"
      },
      "SalesTaxRateInput": {
        "properties": {
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day of the rate; a rate of the same day is replaced."
          },
          "rate": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,3}|(?=[\\d.]{1,8}0*$)\\d{0,3}\\.\\d{0,4}0*$)"
              }
            ],
            "title": "Rate",
            "description": "The rate in percent."
          },
          "source": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where it comes from, e.g. the state's notice."
          }
        },
        "type": "object",
        "required": [
          "valid_from",
          "rate"
        ],
        "title": "SalesTaxRateInput",
        "examples": [
          {
            "rate": "7.5",
            "valid_from": "2027-01-01"
          }
        ]
      },
      "SalesTaxRateOut": {
        "properties": {
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day of the rate (ISO 8601 date)."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "Percent, e.g. `7.25`."
          },
          "source": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source",
            "description": "Where the rate came from, e.g. data-vNext's series."
          }
        },
        "type": "object",
        "required": [
          "valid_from",
          "rate",
          "source"
        ],
        "title": "SalesTaxRateOut"
      },
      "SalesTaxReasonInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why, in a few words; kept in the history."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "SalesTaxReasonInput",
        "examples": [
          {
            "reason": "Filed twice"
          }
        ]
      },
      "SalesTaxRegistrationInput": {
        "properties": {
          "state": {
            "type": "string",
            "pattern": "^US-[A-Z]{2}$",
            "title": "State",
            "description": "The state, ISO 3166-2, e.g. `US-CA`."
          },
          "permit_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 60
              },
              {
                "type": "null"
              }
            ],
            "title": "Permit Number",
            "description": "The state's seller's permit or account number."
          },
          "registered_from": {
            "type": "string",
            "format": "date",
            "title": "Registered From",
            "description": "The first day tax is charged in the state."
          },
          "registered_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registered Until",
            "description": "The last day, when the registration ended; null while in force."
          },
          "filing_frequency": {
            "type": "string",
            "enum": [
              "month",
              "quarter",
              "year"
            ],
            "title": "Filing Frequency",
            "description": "How often the state's return is filed: `month`, `quarter` or `year`."
          },
          "state_rate": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,3}|(?=[\\d.]{1,8}0*$)\\d{0,3}\\.\\d{0,4}0*$)"
              },
              {
                "type": "null"
              }
            ],
            "title": "State Rate",
            "description": "The state rate in percent, from `registered_from`. Omit to take the state base rate data-vNext has (422 `sales_tax_state_rate_unknown` when it has none). Ignored when the state already has its jurisdiction."
          },
          "use_tax_area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Use Tax Area",
            "description": "In the company's own state: the tax area (its code) where it uses what it buys, whose local rates its use tax is self-assessed at; null for the state rate only."
          }
        },
        "type": "object",
        "required": [
          "state",
          "registered_from",
          "filing_frequency"
        ],
        "title": "SalesTaxRegistrationInput",
        "examples": [
          {
            "filing_frequency": "quarter",
            "permit_number": "102-345678",
            "registered_from": "2026-01-01",
            "state": "US-CA"
          }
        ]
      },
      "SalesTaxRegistrationOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the registration."
          },
          "state": {
            "type": "string",
            "title": "State",
            "description": "The state, e.g. `US-CA`."
          },
          "state_name": {
            "type": "string",
            "title": "State Name",
            "description": "The state's name, e.g. `California`."
          },
          "permit_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Permit Number",
            "description": "The state's permit number, or null."
          },
          "registered_from": {
            "type": "string",
            "format": "date",
            "title": "Registered From",
            "description": "First day tax is charged (ISO 8601 date)."
          },
          "registered_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registered Until",
            "description": "Last day, or null while in force."
          },
          "filing_frequency": {
            "type": "string",
            "enum": [
              "month",
              "quarter",
              "year"
            ],
            "title": "Filing Frequency",
            "description": "`month`, `quarter` or `year`."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "The liability account the state's tax is booked to."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "That account's name."
          },
          "use_tax_area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Use Tax Area",
            "description": "The tax area use tax is self-assessed at."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "That account's balance today, credit positive: the tax owed to the state."
          }
        },
        "type": "object",
        "required": [
          "id",
          "state",
          "state_name",
          "permit_number",
          "registered_from",
          "registered_until",
          "filing_frequency",
          "account",
          "account_name",
          "use_tax_area",
          "balance"
        ],
        "title": "SalesTaxRegistrationOut"
      },
      "SalesTaxRegistrationUpdate": {
        "properties": {
          "permit_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 60
              },
              {
                "type": "null"
              }
            ],
            "title": "Permit Number",
            "description": "The state's permit number."
          },
          "registered_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registered Until",
            "description": "The last day of the registration; null while in force."
          },
          "filing_frequency": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "quarter",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Filing Frequency",
            "description": "How often it files; not changed once a return is recorded as filed (409 `sales_tax_frequency_filed`)."
          },
          "use_tax_area": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Use Tax Area",
            "description": "The use tax area's code; null for the state rate only."
          }
        },
        "type": "object",
        "title": "SalesTaxRegistrationUpdate",
        "description": "Only the fields sent change; send `registered_until: null` to reopen a registration.",
        "examples": [
          {
            "registered_until": "2026-12-31"
          }
        ]
      },
      "SalesTaxReturnOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency of the amounts (the company's)."
          },
          "state": {
            "type": "string",
            "title": "State",
            "description": "The state, e.g. `US-CA`."
          },
          "state_name": {
            "type": "string",
            "title": "State Name",
            "description": "The state's name."
          },
          "permit_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Permit Number",
            "description": "The company's permit number in the state."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "`2026-08`, `2026-Q3` or `2026`."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the period."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the period."
          },
          "due_on": {
            "type": "string",
            "format": "date",
            "title": "Due On",
            "description": "The day the return is due with the state."
          },
          "status": {
            "type": "string",
            "enum": [
              "awaiting_approval",
              "due_soon",
              "filed",
              "open",
              "overdue",
              "paid",
              "to_file"
            ],
            "title": "Status",
            "description": "`open` (the period has not ended), `to_file`, `due_soon` (due within 10 days), `overdue` (not recorded as filed by its due day), `awaiting_approval` (recorded as filed, not approved by a second person yet), `filed` or `paid`."
          },
          "figures": {
            "$ref": "#/components/schemas/SalesTaxFigures",
            "description": "The figures from the ledger as it is now."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "The state's liability account."
          },
          "ledger_tax": {
            "type": "string",
            "title": "Ledger Tax",
            "description": "The movement on that account in the period, credit positive, without the entries linked as paying a return."
          },
          "unexplained_difference": {
            "type": "string",
            "title": "Unexplained Difference",
            "description": "`ledger_tax` minus `figures.tax_due`: entries on the account that are not sales tax postings (a manual journal, a payment not linked yet); zero when it ties."
          },
          "changed_since_filing": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Changed Since Filing",
            "description": "The tax due now less the tax filed: postings dated in the period after it was filed (file an amended return with the state); null when not filed."
          },
          "filing": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SalesTaxFilingOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The filing in force, or null."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "state",
          "state_name",
          "permit_number",
          "period",
          "start",
          "end",
          "due_on",
          "status",
          "figures",
          "account",
          "ledger_tax",
          "unexplained_difference",
          "changed_since_filing",
          "filing"
        ],
        "title": "SalesTaxReturnOut"
      },
      "SalesTaxSetupOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "applies": {
            "type": "boolean",
            "title": "Applies",
            "description": "True for a company in the US: its sales use sales tax."
          },
          "on": {
            "type": "string",
            "format": "date",
            "title": "On",
            "description": "The day the rates in force are shown for."
          },
          "categories": {
            "items": {
              "type": "string",
              "enum": [
                "clothing",
                "digital_goods",
                "general",
                "groceries",
                "medical",
                "professional_services",
                "saas"
              ]
            },
            "type": "array",
            "title": "Categories",
            "description": "The product categories, in order."
          },
          "registrations": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxRegistrationOut"
            },
            "type": "array",
            "title": "Registrations",
            "description": "By state."
          },
          "jurisdictions": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxJurisdictionOut"
            },
            "type": "array",
            "title": "Jurisdictions",
            "description": "By state, then code."
          },
          "areas": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxAreaOut"
            },
            "type": "array",
            "title": "Areas",
            "description": "By state, then code."
          },
          "rules": {
            "items": {
              "$ref": "#/components/schemas/SalesTaxCategoryRuleOut"
            },
            "type": "array",
            "title": "Rules",
            "description": "Product taxability by state; a category without a rule is taxed in full."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "applies",
          "on",
          "categories",
          "registrations",
          "jurisdictions",
          "areas",
          "rules"
        ],
        "title": "SalesTaxSetupOut"
      },
      "SalesTeamInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Name",
            "description": "The team's name, unique."
          },
          "member_ids": {
            "items": {
              "type": "string",
              "format": "uuid"
            },
            "type": "array",
            "title": "Member Ids",
            "description": "Its people (`GET /v1/people`); a person may be in several teams."
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "SalesTeamInput",
        "examples": [
          {
            "member_ids": [
              "8b1f2c3d-4e5f-4a6b-9c7d-8e9f0a1b2c3d"
            ],
            "name": "Sales DACH"
          }
        ]
      },
      "SalesTeamOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the team."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          },
          "members": {
            "items": {
              "$ref": "#/components/schemas/Person"
            },
            "type": "array",
            "title": "Members",
            "description": "Its people, by name."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was set up (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "members",
          "created_at"
        ],
        "title": "SalesTeamOut",
        "examples": [
          {
            "created_at": "2026-10-23T08:00:00Z",
            "id": "6c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
            "members": [
              {
                "email": "lena@example.com",
                "id": "8b1f2c3d-4e5f-4a6b-9c7d-8e9f0a1b2c3d",
                "name": "Lena"
              }
            ],
            "name": "Sales DACH"
          }
        ]
      },
      "SalesTeamRef": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the team."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "title": "SalesTeamRef"
      },
      "SalesTeamUpdate": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 80,
            "minLength": 1,
            "title": "Name",
            "description": "The new name."
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "SalesTeamUpdate",
        "examples": [
          {
            "name": "Sales Switzerland"
          }
        ]
      },
      "SalesforceImportResult": {
        "properties": {
          "object": {
            "type": "string",
            "enum": [
              "accounts",
              "contacts",
              "events",
              "notes",
              "opportunities",
              "price_book_entries",
              "price_books",
              "products",
              "tasks",
              "users"
            ],
            "title": "Object",
            "description": "What the file holds."
          },
          "mode": {
            "type": "string",
            "enum": [
              "commit",
              "dry_run"
            ],
            "title": "Mode",
            "description": "`dry_run` (nothing is saved) or `commit` (all or nothing)."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity the import is for."
          },
          "format": {
            "type": "string",
            "enum": [
              "csv",
              "xlsx"
            ],
            "title": "Format",
            "description": "`csv` or `xlsx`, as detected from the file."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "The uploaded file's name."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the file, kept with what it created."
          },
          "rows": {
            "type": "integer",
            "title": "Rows",
            "description": "Data rows in the file (empty rows are skipped)."
          },
          "ok": {
            "type": "boolean",
            "title": "Ok",
            "description": "True when the file has no error: a dry run says a commit would succeed; a commit has succeeded."
          },
          "committed": {
            "type": "boolean",
            "title": "Committed",
            "description": "True only for a commit that saved the records."
          },
          "columns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Columns",
            "description": "The file's columns, as the header names them."
          },
          "mapping": {
            "items": {
              "$ref": "#/components/schemas/FieldMapping"
            },
            "type": "array",
            "title": "Mapping",
            "description": "Each of our fields and the column it is read from: found by its Salesforce name (API name or label), or as `mapping` named it."
          },
          "unused_columns": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unused Columns",
            "description": "Columns of the file no field is read from (Salesforce exports every field; most are not needed)."
          },
          "errors": {
            "items": {
              "$ref": "#/components/schemas/ImportIssue"
            },
            "type": "array",
            "title": "Errors",
            "description": "Every problem found (all of them): a dry run lists them with 200, a commit refuses with 422 and the same list."
          },
          "warnings": {
            "items": {
              "$ref": "#/components/schemas/ImportIssue"
            },
            "type": "array",
            "title": "Warnings",
            "description": "Things worth knowing that do not stop the import: a row skipped, a value shortened, a code made up because the file has none."
          },
          "summary": {
            "$ref": "#/components/schemas/SalesforceSummary",
            "description": "What was (or would be) created."
          }
        },
        "type": "object",
        "required": [
          "object",
          "mode",
          "entity",
          "format",
          "filename",
          "sha256",
          "rows",
          "ok",
          "committed",
          "columns",
          "mapping",
          "unused_columns",
          "errors",
          "warnings",
          "summary"
        ],
        "title": "SalesforceImportResult"
      },
      "SalesforceSummary": {
        "properties": {
          "created": {
            "type": "integer",
            "title": "Created",
            "description": "Rows imported now: each became a record."
          },
          "already_imported": {
            "type": "integer",
            "title": "Already Imported",
            "description": "Rows whose Salesforce id an earlier import already brought over: left as they are, nothing is created twice."
          },
          "skipped": {
            "type": "integer",
            "title": "Skipped",
            "description": "Rows not imported, each with a note saying why (deleted in Salesforce, about a record that was not imported, ...)."
          },
          "records": {
            "additionalProperties": {
              "type": "integer"
            },
            "type": "object",
            "title": "Records",
            "description": "What was created, by kind: `customers`, `deals`, `tasks`, `notes`, `products`, `prices`, `price_lists`, `people_linked`, ..."
          }
        },
        "type": "object",
        "required": [
          "created",
          "already_imported",
          "skipped",
          "records"
        ],
        "title": "SalesforceSummary",
        "description": "What the import created (or, in a dry run, would create)."
      },
      "SampleDataOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The entity's code."
          },
          "customers": {
            "type": "integer",
            "title": "Customers",
            "description": "Sample customers created (0 when they existed already)."
          },
          "vendors": {
            "type": "integer",
            "title": "Vendors",
            "description": "Sample vendors created (0 when they existed already)."
          },
          "invoices": {
            "type": "integer",
            "title": "Invoices",
            "description": "Sales invoices posted."
          },
          "bills": {
            "type": "integer",
            "title": "Bills",
            "description": "Vendor bills posted."
          },
          "payments": {
            "type": "integer",
            "title": "Payments",
            "description": "Payments booked: the first invoice's and the first bill's."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "customers",
          "vendors",
          "invoices",
          "bills",
          "payments"
        ],
        "title": "SampleDataOut",
        "description": "What `POST /v1/entities/{entity}/sample-data` booked."
      },
      "SatisfyInput": {
        "properties": {
          "on": {
            "type": "string",
            "format": "date",
            "title": "On",
            "description": "The day control transferred."
          },
          "evidence": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 3,
            "title": "Evidence",
            "description": "What shows it: a delivery note, an acceptance, a go-live record."
          }
        },
        "type": "object",
        "required": [
          "on",
          "evidence"
        ],
        "title": "SatisfyInput",
        "examples": [
          {
            "evidence": "Acceptance protocol AP-2027-004",
            "on": "2027-01-20"
          }
        ]
      },
      "SavedReportIn": {
        "properties": {
          "definition": {
            "$ref": "#/components/schemas/ReportDefinition",
            "description": "What the report lists."
          },
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "What the report is called; default: the source's name."
          },
          "sharing": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportSharing"
              },
              {
                "type": "null"
              }
            ],
            "description": "Default: only the owner."
          },
          "schedule": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportSchedule"
              },
              {
                "type": "null"
              }
            ],
            "description": "Default: not sent."
          },
          "pinned": {
            "type": "boolean",
            "title": "Pinned",
            "description": "Pin it to the owner's Home at once.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "definition"
        ],
        "title": "SavedReportIn",
        "examples": [
          {
            "definition": {
              "filters": [
                {
                  "field": "kind",
                  "op": "eq",
                  "value": "sales_invoice"
                },
                {
                  "field": "payment",
                  "op": "in",
                  "value": [
                    "open",
                    "overdue"
                  ]
                },
                {
                  "field": "open_amount",
                  "op": "gt",
                  "value": "10000"
                },
                {
                  "field": "country",
                  "op": "eq",
                  "value": "DE"
                }
              ],
              "group_by": "sales_person",
              "source": "sales_invoices",
              "sums": [
                "open_amount"
              ]
            },
            "name": "Unpaid invoices in Germany"
          }
        ]
      },
      "SavedReportOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The report's id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What the report is called."
          },
          "definition": {
            "$ref": "#/components/schemas/ReportDefinition",
            "description": "What the report lists."
          },
          "owner": {
            "$ref": "#/components/schemas/ReportOwner",
            "description": "Who saved it: only they change it."
          },
          "mine": {
            "type": "boolean",
            "title": "Mine",
            "description": "The person asking owns it (and may change it)."
          },
          "sharing": {
            "$ref": "#/components/schemas/ReportSharing",
            "description": "Who else may open it."
          },
          "schedule": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportSchedule"
              },
              {
                "type": "null"
              }
            ],
            "description": "When it is e-mailed; null: never."
          },
          "next_send_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Send At",
            "description": "When it is e-mailed next."
          },
          "last_sent_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Sent At",
            "description": "When it was last e-mailed."
          },
          "last_send_problem": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Send Problem",
            "description": "Why the last e-mail was not sent, if so."
          },
          "pinned": {
            "type": "boolean",
            "title": "Pinned",
            "description": "On the Home of the person asking."
          },
          "path": {
            "type": "string",
            "title": "Path",
            "description": "Where it opens in the app."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was saved."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When it was last changed."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "name",
          "definition",
          "owner",
          "mine",
          "sharing",
          "schedule",
          "next_send_at",
          "last_sent_at",
          "last_send_problem",
          "pinned",
          "path",
          "created_at",
          "updated_at"
        ],
        "title": "SavedReportOut"
      },
      "SavedReportUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "A new name; null: kept."
          },
          "definition": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportDefinition"
              },
              {
                "type": "null"
              }
            ],
            "description": "What the report lists from now on; null: kept."
          },
          "sharing": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportSharing"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who may open it from now on; null: kept."
          },
          "schedule": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ReportSchedule"
              },
              {
                "type": "null"
              }
            ],
            "description": "A schedule replaces the one there; see `unschedule`."
          },
          "unschedule": {
            "type": "boolean",
            "title": "Unschedule",
            "description": "Stop sending it.",
            "default": false
          }
        },
        "type": "object",
        "title": "SavedReportUpdate",
        "examples": [
          {
            "name": "Unpaid in Germany"
          }
        ]
      },
      "ScheduleInput": {
        "properties": {
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "The person who owns the close (`GET /v1/people`); null for nobody. Omitted: unchanged."
          },
          "step_days": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "integer"
                },
                "propertyNames": {
                  "enum": [
                    "checklist",
                    "close",
                    "close_review",
                    "deferred_tax",
                    "depreciation",
                    "forecast_roll",
                    "fx_revaluation",
                    "recurring_invoices"
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Step Days",
            "description": "The working day after the period end each step is due on (0: the period's last day; Monday to Friday count). Only the steps named change; omitted: unchanged."
          },
          "automated_steps": {
            "anyOf": [
              {
                "items": {
                  "type": "string",
                  "enum": [
                    "bank_matching",
                    "checklist",
                    "close_review",
                    "deferred_tax",
                    "depreciation",
                    "forecast_roll",
                    "fx_revaluation",
                    "recurring_invoices"
                  ]
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Automated Steps",
            "description": "The steps the scheduled close job runs for the entity: every day from a period's last day until it is closed, `recurring_invoices` (the invoices due through the period end), `bank_matching` (the deterministic matcher over the statement lines booked through the period end), `depreciation`, `fx_revaluation` and `deferred_tax` (each period-end run once, from its due day, when the checklist says it is due; what it posts waits for a person under the policy rule `close_job_runs_need_a_person`), `checklist` (the close checklist, kept in the job's log) and `close_review` (the close review agent writes the period's close memo, once, when no check fails or from the step's due day; it reads and records issues, it runs no adjustment); and once a period is closed, `forecast_roll`: a new draft of each forecast of the entity that has no version made since the latest close (`POST /v1/plans/{plan_id}/roll` with its defaults; a person reviews and approves it). The job never approves or closes anything. Empty: the job leaves the entity alone (the default). Omitted: unchanged."
          },
          "step_owners": {
            "anyOf": [
              {
                "additionalProperties": {
                  "anyOf": [
                    {
                      "type": "string",
                      "format": "uuid"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "propertyNames": {
                  "enum": [
                    "checklist",
                    "close",
                    "close_review",
                    "deferred_tax",
                    "depreciation",
                    "forecast_roll",
                    "fx_revaluation",
                    "recurring_invoices"
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Step Owners",
            "description": "Who does each step (`GET /v1/people`); null for the close owner. Only the steps named change; omitted: unchanged."
          }
        },
        "type": "object",
        "title": "ScheduleInput",
        "examples": [
          {
            "owner_user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
            "step_days": {
              "close": 4,
              "depreciation": 1
            }
          },
          {
            "automated_steps": [
              "recurring_invoices",
              "checklist"
            ]
          },
          {
            "step_owners": {
              "depreciation": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d"
            }
          }
        ]
      },
      "ScheduleLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Schedule line id."
          },
          "obligation_id": {
            "type": "string",
            "format": "uuid",
            "title": "Obligation Id",
            "description": "The obligation."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "The obligation's line number."
          },
          "plan_version": {
            "type": "integer",
            "title": "Plan Version",
            "description": "The plan version it belongs to."
          },
          "trigger": {
            "type": "string",
            "enum": [
              "event",
              "time"
            ],
            "title": "Trigger",
            "description": "`time` or `event`."
          },
          "period_start": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period Start",
            "description": "A time line: the first day it covers."
          },
          "period_end": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period End",
            "description": "A time line: the last day it covers."
          },
          "recognise_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Recognise On",
            "description": "The day it is revenue; an event line: null until the obligation is satisfied."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Revenue, in the contract's currency."
          },
          "superseded": {
            "type": "boolean",
            "title": "Superseded",
            "description": "Replaced by a later plan version."
          },
          "recognised": {
            "type": "boolean",
            "title": "Recognised",
            "description": "Posted as revenue."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "The recognition entry."
          }
        },
        "type": "object",
        "required": [
          "id",
          "obligation_id",
          "line_no",
          "plan_version",
          "trigger",
          "period_start",
          "period_end",
          "recognise_on",
          "amount",
          "superseded",
          "recognised",
          "journal_entry_id"
        ],
        "title": "ScheduleLineOut"
      },
      "ScheduleOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "configured": {
            "type": "boolean",
            "title": "Configured",
            "description": "false while the entity has no schedule of its own: the defaults are shown."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who owns the close."
          },
          "steps": {
            "items": {
              "$ref": "#/components/schemas/StepDay"
            },
            "type": "array",
            "title": "Steps",
            "description": "Every step, in the order of the close."
          },
          "automated_steps": {
            "items": {
              "type": "string",
              "enum": [
                "bank_matching",
                "checklist",
                "close_review",
                "deferred_tax",
                "depreciation",
                "forecast_roll",
                "fx_revaluation",
                "recurring_invoices"
              ]
            },
            "type": "array",
            "title": "Automated Steps",
            "description": "The steps the scheduled close job runs; empty: none."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who set the schedule last."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "configured",
          "owner",
          "steps",
          "updated_by",
          "updated_at"
        ],
        "title": "ScheduleOut",
        "examples": [
          {
            "automated_steps": [
              "recurring_invoices",
              "checklist"
            ],
            "configured": true,
            "entity": "CH01",
            "owner": {
              "email": "alice@example.com",
              "id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
              "name": "Alice"
            },
            "steps": [
              {
                "due_day": 0,
                "step": "recurring_invoices",
                "title": "Recurring invoices made"
              },
              {
                "due_day": 1,
                "step": "depreciation",
                "title": "Depreciation run"
              }
            ],
            "updated_at": "2026-10-04T08:00:00Z",
            "updated_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            }
          }
        ]
      },
      "ScheduleRequest": {
        "properties": {
          "refresh_schedule": {
            "type": "string",
            "enum": [
              "nightly",
              "off",
              "weekly"
            ],
            "title": "Refresh Schedule",
            "description": "`nightly`: the copy is refreshed every night; `weekly`: once a week; `off`: only when someone refreshes it."
          }
        },
        "type": "object",
        "required": [
          "refresh_schedule"
        ],
        "title": "ScheduleRequest",
        "examples": [
          {
            "refresh_schedule": "nightly"
          }
        ]
      },
      "ScheduleYear": {
        "properties": {
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "Fiscal year of the row."
          },
          "opening_book_value": {
            "type": "string",
            "title": "Opening Book Value",
            "description": "Value at the start of the year, a decimal string."
          },
          "depreciation": {
            "type": "string",
            "title": "Depreciation",
            "description": "Scheduled depreciation of the year."
          },
          "accumulated": {
            "type": "string",
            "title": "Accumulated",
            "description": "Accumulated scheduled depreciation at the end of the year."
          },
          "closing_book_value": {
            "type": "string",
            "title": "Closing Book Value",
            "description": "Value at the end of the year."
          },
          "book_value": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Book Value",
            "description": "Tax books: the accounting book's closing value for the same year."
          },
          "difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Difference",
            "description": "Tax books: `book_value` less this book's closing value."
          }
        },
        "type": "object",
        "required": [
          "fiscal_year",
          "opening_book_value",
          "depreciation",
          "accumulated",
          "closing_book_value"
        ],
        "title": "ScheduleYear"
      },
      "SearchHit": {
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "customer",
              "journal_entry",
              "lead",
              "opportunity",
              "payment",
              "plan",
              "product",
              "purchase_bill",
              "purchase_credit_note",
              "purchase_order",
              "quote",
              "revenue_contract",
              "sales_credit_note",
              "sales_invoice",
              "sales_order",
              "subscription",
              "vendor"
            ],
            "title": "Type",
            "description": "What was found: a sales invoice or credit note, a purchase bill or credit note, a purchase order, a quote, a sales order, a journal entry, a payment (`direction` says which way), a customer, a vendor, a subscription, a revenue contract, a deal (`opportunity`), a lead, a product or a plan (a budget or forecast)."
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the record: `GET /v1/documents/{id}`, `GET /v1/purchase-orders/{id}`, `GET /v1/sales-documents/{id}` (a quote or sales order), `GET /v1/journal-entries/{id}`, `GET /v1/entities/{entity}/parties/{id}`, `GET /v1/subscriptions/{id}`, `GET /v1/revenue-contracts/{id}`, `GET /v1/opportunities/{id}`, `GET /v1/leads/{id}`, `GET /v1/products/{id}` or `GET /v1/plans/{id}`; a payment has no card of its own (see `journal_entry_id`)."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity (company) the record belongs to."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number (`INV-2026-000012`, `PO-2026-0003`), or the code of a customer, vendor or product; null for a draft that has none yet, and for a plan."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The customer or vendor of a document, order, payment, subscription or revenue contract, the customer or prospect of a deal, the name of a customer, vendor, product, plan or lead (a person), or the description of a journal entry."
          },
          "title": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Title",
            "description": "The title of a subscription, revenue contract or deal, a lead's company; else null."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Its status, e.g. `draft`, `posted`, `active`; a deal's stage (`lead` to `won` or `lost`), a lead's status (`new` to `converted`), a product's `active` or `inactive`, a plan's kind (`budget` or `forecast`)."
          },
          "date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Date",
            "description": "Document, order, entry or payment date, the start of a subscription or revenue contract, the expected close of a deal, the day a lead came in; null for a customer, vendor, product or plan."
          },
          "amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "Total of a document, net total of an order, the amount of a payment, the transaction price of a revenue contract or the expected value of a deal, in `currency`; null otherwise."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 currency of `amount`."
          },
          "direction": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "incoming",
                  "outgoing"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Direction",
            "description": "Of a payment: `incoming` (a customer paid) or `outgoing` (a vendor is paid); null otherwise."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "Of a payment: the journal entry it posted, once posted; null otherwise."
          },
          "matched_field": {
            "type": "string",
            "enum": [
              "buyer_reference",
              "code",
              "customer_reference",
              "description",
              "email",
              "external_number",
              "name",
              "number",
              "order_reference",
              "party",
              "payment_reference",
              "reference",
              "source_ref",
              "title",
              "vat_number"
            ],
            "title": "Matched Field",
            "description": "The field the text was found in, e.g. `number` or `payment_reference`."
          },
          "matched_value": {
            "type": "string",
            "title": "Matched Value",
            "description": "That field's value."
          }
        },
        "type": "object",
        "required": [
          "type",
          "id",
          "entity",
          "number",
          "name",
          "title",
          "status",
          "date",
          "amount",
          "currency",
          "direction",
          "journal_entry_id",
          "matched_field",
          "matched_value"
        ],
        "title": "SearchHit"
      },
      "Section": {
        "properties": {
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The statement line, e.g. `pl.opex.other` or `bs.assets.current.cash`."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Sum of the balances of its accounts, in the report's currency."
          },
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/AccountBalance"
            },
            "type": "array",
            "title": "Accounts",
            "description": "The accounts on that line."
          },
          "comparative": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Comparative"
              },
              {
                "type": "null"
              }
            ],
            "description": "As the accounts' `comparative`, for the line; null when not asked for."
          },
          "budget": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Comparative"
              },
              {
                "type": "null"
              }
            ],
            "description": "As the accounts' `budget`, for the line; null when not asked for."
          }
        },
        "type": "object",
        "required": [
          "report_line",
          "amount",
          "accounts"
        ],
        "title": "Section"
      },
      "SendBackInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why the version goes back to draft."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "SendBackInput",
        "examples": [
          {
            "reason": "Marketing figures for Q2 are missing"
          }
        ]
      },
      "SendInput": {
        "properties": {
          "to": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 5,
                "minItems": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "To",
            "description": "Recipient addresses, one to five. Each must be an address of the customer: its e-invoice address (scheme `EM`), its e-mail address or a contact's e-mail address (`allowed_recipients` of `GET /v1/documents/{id}/dispatches`); any other address is refused with 422 until it is added to the customer. Omitted: the customer's e-invoice address if it is an e-mail address, else the e-mail address of a contact whose role says billing or accounting, else the customer's e-mail address."
          },
          "message": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Message",
            "description": "A text of at most 1,000 characters placed before the standard text of the e-mail."
          },
          "format": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "pdf",
                  "zugferd"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Format",
            "description": "`pdf` (default): the invoice PDF; `zugferd`: the hybrid PDF with the EN 16931 XML inside (German entities only; not yet verified for PDF/A-3, see docs/engineering/backlog.md B-55)."
          }
        },
        "type": "object",
        "title": "SendInput",
        "description": "Who gets the invoice and in which form. Every field is optional.",
        "examples": [
          {
            "message": "Please quote the order number when you pay.",
            "to": [
              "buchhaltung@matter-treuhand.example"
            ]
          }
        ]
      },
      "Series": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "metric": {
            "type": "string",
            "enum": [
              "cash",
              "cost_of_sales",
              "dpo",
              "dso",
              "expenses",
              "gross_margin_pct",
              "net_income",
              "operating_expenses",
              "payables",
              "payables_aging",
              "receivables",
              "receivables_aging",
              "revenue",
              "unearned_revenue",
              "working_capital"
            ],
            "title": "Metric",
            "description": "The metric, as requested."
          },
          "unit": {
            "type": "string",
            "enum": [
              "amount",
              "days",
              "percent"
            ],
            "title": "Unit",
            "description": "`amount` (the functional currency), `percent` or `days`; ratios have one decimal."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; amounts are in it."
          },
          "granularity": {
            "type": "string",
            "enum": [
              "month",
              "quarter",
              "year"
            ],
            "title": "Granularity",
            "description": "The size of the periods."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the range (ISO 8601)."
          },
          "by": {
            "type": "string",
            "enum": [
              "account",
              "none",
              "report_line"
            ],
            "title": "By",
            "description": "How the metric is split into `lines`."
          },
          "periods": {
            "items": {
              "$ref": "#/components/schemas/SeriesPeriod"
            },
            "type": "array",
            "title": "Periods",
            "description": "The calendar months, quarters or years of the range, the first and last clamped to it."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/SeriesLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "One line, or one per report line, account or aging bucket."
          },
          "totals": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "array",
            "title": "Totals",
            "description": "Per period, the sum of the lines (the line itself for a ratio). For a flow, the sum over all periods is the report total for the range."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "metric",
          "unit",
          "currency",
          "granularity",
          "start",
          "end",
          "by",
          "periods",
          "lines",
          "totals"
        ],
        "title": "Series"
      },
      "SeriesLine": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "Which line: the metric's own key when not split, else the report line (`pl.opex.other`), the account code (`6500`) or, for an aging, the bucket (`current`, `1-30`, `31-60`, `61-90`, `90+`).",
            "examples": [
              "pl.opex.other"
            ]
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "A readable name: the metric's English title, the report line, or the account code and name."
          },
          "values": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "array",
            "title": "Values",
            "description": "One value per period, in the order of `periods`; null where a ratio has no denominator (no revenue in the period)."
          }
        },
        "type": "object",
        "required": [
          "key",
          "label",
          "values"
        ],
        "title": "SeriesLine"
      },
      "SeriesPeriod": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "`2026-09` for a month, `2026-Q3` for a quarter, `2026` for a year.",
            "examples": [
              "2026-09"
            ]
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day the period covers inside the requested range (ISO 8601)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day the period covers inside the requested range (ISO 8601). A flow is the movement from `start` to `end`; a stock or an aging is as of `end`."
          }
        },
        "type": "object",
        "required": [
          "key",
          "start",
          "end"
        ],
        "title": "SeriesPeriod"
      },
      "ServiceHealth": {
        "properties": {
          "generated_at": {
            "type": "string",
            "format": "date-time",
            "title": "Generated At",
            "description": "When the figures were read from Cloud Monitoring (ISO 8601, UTC). The endpoint answers from a cache of at most 60 seconds."
          },
          "status": {
            "type": "string",
            "enum": [
              "degraded",
              "ok",
              "unavailable"
            ],
            "title": "Status",
            "description": "`ok`; `degraded` when some part could not be read (see `problems`); `unavailable` when nothing could (monitoring not configured, or no permission)."
          },
          "services": {
            "items": {
              "$ref": "#/components/schemas/ServiceOut"
            },
            "type": "array",
            "title": "Services",
            "description": "Both services, ERP first."
          },
          "uptime_checks": {
            "items": {
              "$ref": "#/components/schemas/UptimeCheckOut"
            },
            "type": "array",
            "title": "Uptime Checks",
            "description": "The synthetic checks."
          },
          "problems": {
            "items": {
              "$ref": "#/components/schemas/Problem"
            },
            "type": "array",
            "title": "Problems",
            "description": "Parts that could not be read; empty when ok."
          }
        },
        "type": "object",
        "required": [
          "generated_at",
          "status",
          "services",
          "uptime_checks",
          "problems"
        ],
        "title": "ServiceHealth"
      },
      "ServiceOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "The Cloud Run service: `erp-api` or `datavnext-api`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The service's name for people."
          },
          "slos": {
            "items": {
              "$ref": "#/components/schemas/SloOut"
            },
            "type": "array",
            "title": "Slos",
            "description": "Its objectives, availability first."
          },
          "latency_p95_ms_24h": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "number"
                },
                {
                  "type": "null"
                }
              ]
            },
            "type": "object",
            "title": "Latency P95 Ms 24H",
            "description": "The 95th percentile of the application's response time over the last 24 hours, in milliseconds, by request class: `read`, `report` (statements, aging, analytics, FX exposure), `write`, `heavy` (PDFs, exports, imports, VAT returns, period close; no objective). Null for a class without requests."
          },
          "deploy": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/DeployOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "The deploy state; null when Cloud Run could not be read (see `problems`)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "slos",
          "latency_p95_ms_24h",
          "deploy"
        ],
        "title": "ServiceOut"
      },
      "SettingsInput": {
        "properties": {
          "tolerance_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 10.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Tolerance Percent",
            "description": "Variance allowed as a percent of the expected amount."
          },
          "tolerance_amount": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 1000.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Tolerance Amount",
            "description": "Variance allowed per line at most, in the order's currency."
          },
          "tolerance_bill_amount": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 10000.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Tolerance Bill Amount",
            "description": "Overcharge allowed per bill in total at most (the lines' variances added).",
            "default": "20.00"
          }
        },
        "type": "object",
        "required": [
          "tolerance_percent",
          "tolerance_amount"
        ],
        "title": "SettingsInput",
        "examples": [
          {
            "tolerance_amount": "5.00",
            "tolerance_bill_amount": "20.00",
            "tolerance_percent": "2"
          }
        ]
      },
      "SettingsOut": {
        "properties": {
          "tolerance_percent": {
            "type": "string",
            "title": "Tolerance Percent",
            "description": "Variance allowed as a percent of the expected amount."
          },
          "tolerance_amount": {
            "type": "string",
            "title": "Tolerance Amount",
            "description": "Variance allowed per line at most, in the order's currency."
          },
          "tolerance_bill_amount": {
            "type": "string",
            "title": "Tolerance Bill Amount",
            "description": "Overcharge allowed per bill in total at most (the lines' variances added).",
            "default": "20.00"
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code the tolerances belong to."
          },
          "default": {
            "type": "boolean",
            "title": "Default",
            "description": "True while the entity uses the built-in tolerances."
          },
          "updated_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated By",
            "description": "Who set them last; null while the built-in defaults apply."
          },
          "updated_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Updated At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "tolerance_percent",
          "tolerance_amount",
          "entity",
          "default"
        ],
        "title": "SettingsOut"
      },
      "SettlementInput": {
        "properties": {
          "loan": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Loan",
            "description": "Settle the loan's accrued interest; or name a `dividend`."
          },
          "dividend": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Dividend",
            "description": "Settle a declared group dividend: the id of its `dividend_declared` movement."
          },
          "value_date": {
            "type": "string",
            "format": "date",
            "title": "Value Date",
            "description": "The day of the payment."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "In the currency of what is settled; at most what is open."
          },
          "payer_bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payer Bank Account",
            "description": "The paying entity's bank account code; default the loan's (for a dividend the account with the role `bank`)."
          },
          "payee_bank_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payee Bank Account",
            "description": "The receiving entity's bank account code; default as above."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Your reference."
          }
        },
        "type": "object",
        "required": [
          "value_date",
          "amount"
        ],
        "title": "SettlementInput",
        "examples": [
          {
            "amount": "1250.00",
            "loan": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            "value_date": "2026-11-05"
          }
        ]
      },
      "SetupDone": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The code of the company created in Production."
          },
          "standard": {
            "type": "string",
            "title": "Standard",
            "description": "The accounting standard it reports under."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency of its books."
          },
          "chart": {
            "type": "string",
            "title": "Chart",
            "description": "The chart template its accounts were copied from."
          },
          "framework": {
            "type": "string",
            "title": "Framework",
            "description": "Its accounting framework."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year whose periods were opened."
          },
          "tax_settings": {
            "type": "boolean",
            "title": "Tax Settings",
            "description": "True when its tax settings (method and return period) were saved; false where the country has none to set (US sales tax) or keeps the defaults (Liechtenstein).",
            "default": false
          },
          "test_environment": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/CopyOut"
              },
              {
                "type": "null"
              }
            ],
            "description": "Test, the test copy made of Production; null if it failed."
          },
          "test_environment_problem": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Test Environment Problem",
            "description": "Why Test could not be made (Production stands); make it from Settings, Test copies."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "standard",
          "currency",
          "chart",
          "framework",
          "fiscal_year"
        ],
        "title": "SetupDone"
      },
      "SetupInput": {
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "The company's legal name."
          },
          "country": {
            "type": "string",
            "pattern": "^[A-Z]{2}$",
            "title": "Country",
            "description": "Where it is registered (`GET /v1/setup/options`)."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}-[A-Z0-9]{1,3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "The state (US) or province (Canada), ISO 3166-2; required there, refused elsewhere."
          },
          "standard": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Standard",
            "description": "The accounting standard's id, one of the country's. Omitted: the country's first (`GET /v1/setup/options` lists them, the default first)."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "The currency of the books, one the country allows. Cannot be changed later. Omitted: the country's currency."
          },
          "fiscal_year_start_month": {
            "type": "integer",
            "maximum": 12.0,
            "minimum": 1.0,
            "title": "Fiscal Year Start Month",
            "description": "The month the fiscal year starts, 1 to 12.",
            "default": 1
          },
          "tax_period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Period",
            "description": "The tax return period, one of the country's; default: its first."
          },
          "tax_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 40
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Number",
            "description": "The tax registration number, when asked."
          },
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Number."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town."
          },
          "industry": {
            "type": "string",
            "enum": [
              "ecommerce",
              "general",
              "hospitality",
              "manufacturing",
              "retail",
              "services",
              "trade"
            ],
            "title": "Industry",
            "description": "The company's industry (`GET /v1/industries`): `general`, `hospitality`, `services`, `trade`, `retail`, `ecommerce` or `manufacturing`. It puts the screens of the industry first in the app's menu and on its Home; it switches nothing off, and every operation works the same in every industry. Default `general`; it can be changed later.",
            "default": "general"
          }
        },
        "type": "object",
        "required": [
          "name",
          "country"
        ],
        "title": "SetupInput",
        "examples": [
          {
            "building_number": "100",
            "country": "CA",
            "currency": "CAD",
            "fiscal_year_start_month": 1,
            "name": "Maple Analytics Inc.",
            "postal_code": "M5X 1A9",
            "standard": "aspe",
            "street": "King Street West",
            "subdivision": "CA-ON",
            "tax_number": "123456789RT0001",
            "tax_period": "quarter",
            "town": "Toronto"
          }
        ]
      },
      "SetupOptions": {
        "properties": {
          "countries": {
            "items": {
              "$ref": "#/components/schemas/CountryOption"
            },
            "type": "array",
            "title": "Countries",
            "description": "The countries served, by name."
          }
        },
        "type": "object",
        "required": [
          "countries"
        ],
        "title": "SetupOptions"
      },
      "SetupStatus": {
        "properties": {
          "needed": {
            "type": "boolean",
            "title": "Needed",
            "description": "True while the organization has no company and is not a test organization: its first administrator is asked to set it up."
          },
          "can_complete": {
            "type": "boolean",
            "title": "Can Complete",
            "description": "True when the caller may set it up (an administrator, a person)."
          }
        },
        "type": "object",
        "required": [
          "needed",
          "can_complete"
        ],
        "title": "SetupStatus"
      },
      "ShopifyAuthorize": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company.",
            "examples": [
              "CH01"
            ]
          },
          "shop_domain": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]{0,59}\\.myshopify\\.com$",
            "title": "Shop Domain",
            "description": "The shop's own address."
          },
          "client_id": {
            "type": "string",
            "maxLength": 200,
            "minLength": 10,
            "title": "Client Id",
            "description": "The client id of the company's app."
          },
          "client_secret": {
            "type": "string",
            "maxLength": 500,
            "minLength": 10,
            "title": "Client Secret",
            "description": "That app's client secret: it travels sealed in `state` and checks the shop's answer; never shown again."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "shop_domain",
          "client_id",
          "client_secret"
        ],
        "title": "ShopifyAuthorize",
        "examples": [
          {
            "client_id": "3f5e8a1b9c2d4e6f7a8b9c0d1e2f3a4b",
            "client_secret": "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",
            "entity": "CH01",
            "shop_domain": "alpine-goods.myshopify.com"
          }
        ]
      },
      "ShopifyAuthorizeOut": {
        "properties": {
          "url": {
            "type": "string",
            "title": "Url",
            "description": "The shop's consent page: open it in the browser."
          },
          "redirect_uri": {
            "type": "string",
            "title": "Redirect Uri",
            "description": "Where it sends the browser back."
          }
        },
        "type": "object",
        "required": [
          "url",
          "redirect_uri"
        ],
        "title": "ShopifyAuthorizeOut"
      },
      "ShopifyCallbackInput": {
        "properties": {
          "query": {
            "type": "string",
            "maxLength": 4000,
            "minLength": 1,
            "title": "Query",
            "description": "The query string the shop's consent page sent the browser back with, as it came (its signature covers every parameter)."
          }
        },
        "type": "object",
        "required": [
          "query"
        ],
        "title": "ShopifyCallbackInput",
        "examples": [
          {
            "query": "code=0907a61c0c8d55e99db179b68161bc00&hmac=700e2d…&shop=alpine-goods.myshopify.com&state=eyJvcmciOiI….Xq3v…&timestamp=1793017200"
          }
        ]
      },
      "ShopifyConnectInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the company.",
            "examples": [
              "CH01"
            ]
          },
          "shop_domain": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9-]{0,59}\\.myshopify\\.com$",
            "title": "Shop Domain",
            "description": "The shop's own address, `<name>.myshopify.com` (in the shop's admin under Settings, Domains)."
          },
          "client_id": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 10
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Id",
            "description": "The client id of the company's app, made in Shopify's Dev Dashboard and installed on the shop; with `client_secret`."
          },
          "client_secret": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 10
              },
              {
                "type": "null"
              }
            ],
            "title": "Client Secret",
            "description": "That app's client secret. Kept sealed, never shown again."
          },
          "access_token": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 10
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Token",
            "description": "Instead of an app's client id and secret: a custom app's Admin API access token (`shpat_...`). Kept sealed, never shown again."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "shop_domain"
        ],
        "title": "ShopifyConnectInput",
        "examples": [
          {
            "client_id": "3f5e8a1b9c2d4e6f7a8b9c0d1e2f3a4b",
            "client_secret": "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",
            "entity": "CH01",
            "shop_domain": "alpine-goods.myshopify.com"
          },
          {
            "access_token": "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",
            "entity": "CH01",
            "shop_domain": "alpine-goods.myshopify.com"
          }
        ]
      },
      "ShopifyConnection": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the connection."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company whose books the shop feeds."
          },
          "shop_domain": {
            "type": "string",
            "title": "Shop Domain",
            "description": "The shop's own address, `<name>.myshopify.com`."
          },
          "shop_name": {
            "type": "string",
            "title": "Shop Name",
            "description": "The shop's name."
          },
          "admin_url": {
            "type": "string",
            "title": "Admin Url",
            "description": "The shop's admin in Shopify."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The shop's currency."
          },
          "taxes_included": {
            "type": "boolean",
            "title": "Taxes Included",
            "description": "Whether the shop's prices include the tax; Stabiso's list prices are net, so they are worked out from them."
          },
          "method": {
            "type": "string",
            "enum": [
              "app",
              "consent",
              "token"
            ],
            "title": "Method",
            "description": "`app`: with an app's client id and secret; `consent`: the app let in on the shop's consent page; `token`: with a custom app's access token."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "reconnect"
            ],
            "title": "Status",
            "description": "`reconnect`: the shop stopped accepting the app; connect again."
          },
          "products_read_to": {
            "type": "string",
            "format": "date-time",
            "title": "Products Read To",
            "description": "The products are read up to here (UTC)."
          },
          "last_sync_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Sync At",
            "description": "When the shop was last read (UTC)."
          },
          "last_error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Error",
            "description": "Why the last round failed, in plain words."
          },
          "products": {
            "type": "integer",
            "title": "Products",
            "description": "Variants of the shop sold as products here."
          },
          "orders_read_to": {
            "type": "string",
            "format": "date-time",
            "title": "Orders Read To",
            "description": "The orders are read up to here (UTC); orders placed before the shop was connected are not taken."
          },
          "orders": {
            "type": "integer",
            "title": "Orders",
            "description": "The shop's orders taken into the books."
          },
          "orders_open": {
            "type": "integer",
            "title": "Orders Open",
            "description": "Of them, the ones not yet sent, invoiced and paid in full."
          },
          "orders_with_problems": {
            "type": "integer",
            "title": "Orders With Problems",
            "description": "Of them, the ones a step of which was refused (`GET .../orders`, `problem`)."
          },
          "linked_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Linked By",
            "description": "Who connected it."
          },
          "linked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Linked At",
            "description": "When it was connected (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "shop_domain",
          "shop_name",
          "admin_url",
          "currency",
          "taxes_included",
          "method",
          "status",
          "products_read_to",
          "last_sync_at",
          "last_error",
          "products",
          "orders_read_to",
          "orders",
          "orders_open",
          "orders_with_problems",
          "linked_by",
          "linked_at"
        ],
        "title": "ShopifyConnection"
      },
      "ShopifyOrderCreditNote": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the credit note (`GET /v1/documents/{document_id}`)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number; null before it is posted."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `posted`, `rejected` or `void`."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Its total, with Stabiso's VAT."
          },
          "refunded": {
            "type": "string",
            "title": "Refunded",
            "description": "What the shop refunded."
          },
          "paid": {
            "type": "boolean",
            "title": "Paid",
            "description": "Whether the payment out of the payment provider's balance paid it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status",
          "total",
          "refunded",
          "paid"
        ],
        "title": "ShopifyOrderCreditNote"
      },
      "ShopifyOrderInvoice": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the invoice (`GET /v1/documents/{document_id}`)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number; null before it is posted."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `posted`, `rejected` or `void`."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Its total, with Stabiso's VAT."
          },
          "charged": {
            "type": "string",
            "title": "Charged",
            "description": "What the shop charged for the same goods."
          },
          "paid": {
            "type": "boolean",
            "title": "Paid",
            "description": "Whether the receipt to the payment provider's balance paid it."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status",
          "total",
          "charged",
          "paid"
        ],
        "title": "ShopifyOrderInvoice"
      },
      "ShopifyOrderOut": {
        "properties": {
          "order_id": {
            "type": "integer",
            "title": "Order Id",
            "description": "Shopify's id of the order."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The order's name in the shop, e.g. `#1001`."
          },
          "placed_at": {
            "type": "string",
            "format": "date-time",
            "title": "Placed At",
            "description": "When it was placed (UTC)."
          },
          "customer": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Customer",
            "description": "The buyer's name, or `null` for a guest; the customer is the sales order's."
          },
          "paid": {
            "type": "boolean",
            "title": "Paid",
            "description": "Whether the customer paid it in the shop."
          },
          "charged": {
            "type": "string",
            "title": "Charged",
            "description": "What the shop charged for it, in the shop's currency."
          },
          "sales_order_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Order Id",
            "description": "Id of its sales order (`GET /v1/sales-documents/{document}`); null until made."
          },
          "sales_order": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sales Order",
            "description": "Number of its sales order."
          },
          "state": {
            "type": "string",
            "enum": [
              "cancelled",
              "done",
              "open"
            ],
            "title": "State",
            "description": "`open`: not yet sent, invoiced and paid in full; `done`; `cancelled` in the shop before anything was invoiced."
          },
          "problem": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Problem",
            "description": "Why the last step on it was refused, in plain words; it is done again in the next round."
          },
          "invoices": {
            "items": {
              "$ref": "#/components/schemas/ShopifyOrderInvoice"
            },
            "type": "array",
            "title": "Invoices",
            "description": "The invoice of each fulfilment, the oldest first."
          },
          "purchase_orders": {
            "items": {
              "$ref": "#/components/schemas/ShopifyOrderPurchase"
            },
            "type": "array",
            "title": "Purchase Orders",
            "description": "The purchase orders of its drop-shipped goods, one per supplier."
          },
          "credit_notes": {
            "items": {
              "$ref": "#/components/schemas/ShopifyOrderCreditNote"
            },
            "type": "array",
            "title": "Credit Notes",
            "description": "The credit note of each refund of goods sent, the oldest first; `paid` once paid out of the payment provider's balance."
          }
        },
        "type": "object",
        "required": [
          "order_id",
          "name",
          "placed_at",
          "customer",
          "paid",
          "charged",
          "sales_order_id",
          "sales_order",
          "state",
          "problem",
          "invoices",
          "purchase_orders",
          "credit_notes"
        ],
        "title": "ShopifyOrderOut"
      },
      "ShopifyOrderPurchase": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the purchase order (`GET /v1/purchase-orders/{id}`)."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Code of the supplier who ships the goods."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Its status, e.g. `pending_approval`, `open`, `closed`."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "vendor",
          "status"
        ],
        "title": "ShopifyOrderPurchase"
      },
      "ShopifyPayoutOut": {
        "properties": {
          "payout_id": {
            "type": "integer",
            "title": "Payout Id",
            "description": "Shopify's id of the payout."
          },
          "issued_at": {
            "type": "string",
            "format": "date-time",
            "title": "Issued At",
            "description": "When Shopify issued it (UTC)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "Its status in Shopify: `SCHEDULED`, `IN_TRANSIT`, `PAID`, `FAILED` or `CANCELED`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency it is paid out in."
          },
          "net": {
            "type": "string",
            "title": "Net",
            "description": "What reaches the bank."
          },
          "fees": {
            "type": "string",
            "title": "Fees",
            "description": "The fees Shopify kept of it."
          },
          "adjustments": {
            "type": "string",
            "title": "Adjustments",
            "description": "What chargebacks and other adjustments took from the balance (negative) or gave back."
          },
          "state": {
            "type": "string",
            "enum": [
              "booked",
              "open"
            ],
            "title": "State",
            "description": "`booked` once it is on its way to the bank and what it kept is booked against the payment provider's balance; else `open`."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "Id of the entry that booked its fees and adjustments (`GET /v1/journal-entries/{entry_id}`); null when it kept nothing or is open."
          },
          "journal_entry": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry",
            "description": "Number of that entry once posted."
          },
          "in_bank": {
            "type": "boolean",
            "title": "In Bank",
            "description": "Whether a bank statement line was posted as this payout to the balance."
          },
          "problem": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Problem",
            "description": "Why it was not booked, in plain words; it is tried again in the next round."
          }
        },
        "type": "object",
        "required": [
          "payout_id",
          "issued_at",
          "status",
          "currency",
          "net",
          "fees",
          "adjustments",
          "state",
          "journal_entry_id",
          "journal_entry",
          "in_bank",
          "problem"
        ],
        "title": "ShopifyPayoutOut"
      },
      "ShopifySetup": {
        "properties": {
          "available": {
            "type": "boolean",
            "title": "Available",
            "description": "Whether a shop can be connected on this system (false: secrets could not be kept sealed)."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "What the shop's app must be allowed (its Admin API access scopes)."
          },
          "redirect_uri": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Redirect Uri",
            "description": "Where the shop's consent page sends the browser back: add it to the app's allowed redirection URLs to connect on the consent page."
          },
          "connections": {
            "items": {
              "$ref": "#/components/schemas/ShopifyConnection"
            },
            "type": "array",
            "title": "Connections",
            "description": "The companies connected."
          }
        },
        "type": "object",
        "required": [
          "available",
          "scopes",
          "redirect_uri",
          "connections"
        ],
        "title": "ShopifySetup"
      },
      "ShopifySupplierInput": {
        "properties": {
          "shop_vendor": {
            "type": "string",
            "maxLength": 255,
            "minLength": 1,
            "title": "Shop Vendor",
            "description": "The vendor the shop's products name."
          },
          "vendor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor",
            "description": "Code (or id) of the company's active vendor who ships them to the customers; null when the company ships them itself."
          }
        },
        "type": "object",
        "required": [
          "shop_vendor",
          "vendor"
        ],
        "title": "ShopifySupplierInput",
        "examples": [
          {
            "shop_vendor": "Alpine Outfitters",
            "vendor": "V-00004"
          }
        ]
      },
      "ShopifySupplierOut": {
        "properties": {
          "shop_vendor": {
            "type": "string",
            "title": "Shop Vendor",
            "description": "A vendor the shop's products name."
          },
          "variants": {
            "type": "integer",
            "title": "Variants",
            "description": "The variants of its products Stabiso sells."
          },
          "without_cost": {
            "type": "integer",
            "title": "Without Cost",
            "description": "Those of them without a cost per item in the shop: a drop-shipped one raises no purchase order until it has one."
          },
          "vendor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor",
            "description": "Code of the company's vendor who ships its products (drop shipping); null when the company ships them itself."
          },
          "vendor_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Name",
            "description": "That vendor's name."
          }
        },
        "type": "object",
        "required": [
          "shop_vendor",
          "variants",
          "without_cost",
          "vendor",
          "vendor_name"
        ],
        "title": "ShopifySupplierOut"
      },
      "ShopifySyncOut": {
        "properties": {
          "read": {
            "type": "integer",
            "title": "Read",
            "description": "Variants read from the shop."
          },
          "new_products": {
            "type": "integer",
            "title": "New Products",
            "description": "Products made of them, or found by their SKU."
          },
          "updated_products": {
            "type": "integer",
            "title": "Updated Products",
            "description": "Products whose name, price or status changed."
          },
          "orders_read": {
            "type": "integer",
            "title": "Orders Read",
            "description": "Orders read from the shop."
          },
          "new_orders": {
            "type": "integer",
            "title": "New Orders",
            "description": "Orders taken into the books."
          },
          "purchase_orders": {
            "type": "integer",
            "title": "Purchase Orders",
            "description": "Purchase orders raised with drop shippers."
          },
          "invoiced": {
            "type": "integer",
            "title": "Invoiced",
            "description": "Fulfilments invoiced."
          },
          "paid": {
            "type": "integer",
            "title": "Paid",
            "description": "Invoices paid to the payment provider's balance."
          },
          "problems": {
            "type": "integer",
            "title": "Problems",
            "description": "Orders a step of which was refused."
          },
          "refunds": {
            "type": "integer",
            "title": "Refunds",
            "description": "Refunds settled: credit notes of the goods refunded, paid out of the payment provider's balance."
          },
          "payouts": {
            "type": "integer",
            "title": "Payouts",
            "description": "Payouts of Shopify Payments booked: their fees and chargebacks against the payment provider's balance."
          },
          "connection": {
            "$ref": "#/components/schemas/ShopifyConnection",
            "description": "The connection after the round."
          }
        },
        "type": "object",
        "required": [
          "read",
          "new_products",
          "updated_products",
          "orders_read",
          "new_orders",
          "purchase_orders",
          "invoiced",
          "paid",
          "problems",
          "refunds",
          "payouts",
          "connection"
        ],
        "title": "ShopifySyncOut"
      },
      "ShopifyVariantOut": {
        "properties": {
          "variant_id": {
            "type": "integer",
            "title": "Variant Id",
            "description": "Shopify's id of the variant."
          },
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Id of the product it is sold as here."
          },
          "product": {
            "type": "string",
            "title": "Product",
            "description": "Code of that product."
          },
          "sku": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Sku",
            "description": "The variant's SKU in Shopify."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The product's title, and the variant's when it has options."
          },
          "price": {
            "type": "string",
            "title": "Price",
            "description": "Its price in the shop's currency, as the shop shows it."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "The Shopify product's status: `ACTIVE`, `DRAFT`, `ARCHIVED`."
          },
          "vendor": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor",
            "description": "The product's vendor in the shop."
          },
          "cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cost",
            "description": "The variant's cost per item in the shop's currency; null when it has none."
          },
          "read_at": {
            "type": "string",
            "format": "date-time",
            "title": "Read At",
            "description": "When it was last read (UTC)."
          }
        },
        "type": "object",
        "required": [
          "variant_id",
          "product_id",
          "product",
          "sku",
          "name",
          "price",
          "status",
          "vendor",
          "cost",
          "read_at"
        ],
        "title": "ShopifyVariantOut"
      },
      "SkippedBill": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the bill."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Number of the bill."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "Vendor code."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "Name of the vendor."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the bill."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "Open amount of the bill."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Why, as listed under `skipped`: see the codes there."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why it is left out, in words."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "vendor",
          "vendor_name",
          "currency",
          "open",
          "code",
          "reason"
        ],
        "title": "SkippedBill"
      },
      "SkippedInvoice": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Invoice number."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Customer name."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "Open amount."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Why it is not proposed, as an error code."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why, in plain English."
          },
          "details": {
            "additionalProperties": true,
            "type": "object",
            "title": "Details",
            "description": "The values named."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "customer",
          "customer_name",
          "open",
          "code",
          "reason"
        ],
        "title": "SkippedInvoice"
      },
      "SlaOut": {
        "properties": {
          "due_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due At",
            "description": "When it is due (UTC); none: no target."
          },
          "met_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Met At",
            "description": "When it was met (UTC)."
          },
          "state": {
            "type": "string",
            "enum": [
              "breached",
              "met",
              "none",
              "paused",
              "running"
            ],
            "title": "State",
            "description": "`none` (no target), `running`, `paused` (waiting on the customer or closed), `met` or `breached` (late, or met late)."
          },
          "minutes_left": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Minutes Left",
            "description": "Working minutes until it is due while it runs (negative: overdue)."
          }
        },
        "type": "object",
        "required": [
          "due_at",
          "met_at",
          "state",
          "minutes_left"
        ],
        "title": "SlaOut"
      },
      "SlaTarget": {
        "properties": {
          "first_response_minutes": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 525600.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "First Response Minutes",
            "description": "Working minutes to the first reply."
          },
          "resolution_minutes": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 525600.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolution Minutes",
            "description": "Working minutes to the resolution; the time a case waits on the customer or is closed does not count."
          }
        },
        "type": "object",
        "title": "SlaTarget"
      },
      "SloOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "The objective's id in Cloud Monitoring, for example `availability`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What it promises, in words."
          },
          "goal": {
            "type": "number",
            "title": "Goal",
            "description": "The internal target as a fraction of good events, for example `0.999`. The customer-facing commitment is lower on purpose (docs/legal/sla-draft.md)."
          },
          "window_days": {
            "type": "integer",
            "title": "Window Days",
            "description": "The rolling window the compliance is measured over."
          },
          "compliance": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Compliance",
            "description": "The fraction of good events in the window so far; null without data."
          },
          "budget_remaining": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Budget Remaining",
            "description": "The share of the error budget still unspent: `1` untouched, `0` spent, negative when the objective is missed; null without data."
          },
          "status": {
            "type": "string",
            "enum": [
              "at_risk",
              "breached",
              "no_data",
              "ok"
            ],
            "title": "Status",
            "description": "`ok`; `at_risk` when less than a quarter of the budget is left; `breached` when the budget is spent; `no_data` when the window holds no valid events yet."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "goal",
          "window_days",
          "compliance",
          "budget_remaining",
          "status"
        ],
        "title": "SloOut",
        "description": "One service level objective of a service, over its rolling window."
      },
      "Source": {
        "properties": {
          "authority": {
            "type": "string",
            "title": "Authority",
            "description": "Publisher, e.g. 'European Commission', 'IRS'."
          },
          "url": {
            "type": "string",
            "minLength": 1,
            "format": "uri",
            "title": "Url",
            "description": "Address of the source, an http or https URL."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Legal or paragraph reference, e.g. 'UStG §12', 'IAS 16.31'."
          },
          "verified_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Verified At",
            "description": "Date a maintainer last checked the value against the source."
          },
          "kind": {
            "type": "string",
            "enum": [
              "official",
              "secondary"
            ],
            "title": "Kind",
            "description": "'official' = publisher of the law or data; 'secondary' = professional summary used where the official page could not be checked.",
            "default": "official"
          }
        },
        "type": "object",
        "required": [
          "authority",
          "url"
        ],
        "title": "Source"
      },
      "SourceFileOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the stored file."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "What the file is, e.g. `vendor_bill`."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "File name as uploaded."
          },
          "content_type": {
            "type": "string",
            "title": "Content Type",
            "description": "Media type of the file."
          },
          "size": {
            "type": "integer",
            "title": "Size",
            "description": "Size in bytes."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the file, hex."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the file was stored (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "filename",
          "content_type",
          "size",
          "sha256",
          "created_at"
        ],
        "title": "SourceFileOut",
        "description": "The stored original of a document; the file is GET /v1/documents/{id}/file."
      },
      "SspInput": {
        "properties": {
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code, e.g. `CHF`. Omitted: the entity's functional currency."
          },
          "ssp": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Ssp",
            "description": "The price the product sells for on its own, per unit and period."
          },
          "price_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Period",
            "description": "`month` or `year` for a recurring product (the price of one unit for that long); omitted for a one-off product (the price of one unit)."
          },
          "ssp_basis": {
            "type": "string",
            "maxLength": 2000,
            "minLength": 3,
            "title": "Ssp Basis",
            "description": "How it was established (IFRS 15.77-79): an observable price, adjusted market assessment, expected cost plus a margin, or the residual approach, and the evidence."
          },
          "valid_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid From",
            "description": "The first day it applies; omitted: today."
          }
        },
        "type": "object",
        "required": [
          "ssp",
          "ssp_basis"
        ],
        "title": "SspInput",
        "examples": [
          {
            "currency": "CHF",
            "price_period": "month",
            "ssp": "50.00",
            "ssp_basis": "Observable: the list price, at which 90 % of seats sold in 2026 without a discount (IFRS 15.77).",
            "valid_from": "2026-01-01"
          }
        ]
      },
      "SspOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "SSP id."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency."
          },
          "ssp": {
            "type": "string",
            "title": "Ssp",
            "description": "Standalone selling price of one unit."
          },
          "price_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "year"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Price Period",
            "description": "Per `month` or `year`, or per unit."
          },
          "ssp_basis": {
            "type": "string",
            "title": "Ssp Basis",
            "description": "How it was established."
          },
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day it applies."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it (a person)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "currency",
          "ssp",
          "price_period",
          "ssp_basis",
          "valid_from",
          "created_by",
          "created_at"
        ],
        "title": "SspOut"
      },
      "StageInput": {
        "properties": {
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "lost",
              "negotiation",
              "proposal",
              "qualified",
              "won"
            ],
            "title": "Stage",
            "description": "The new stage: `lead` (10 %), `qualified` (25 %), `proposal` (50 %), `negotiation` (75 %), `won` (100 %) or `lost` (0 %)."
          },
          "probability": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Probability",
            "description": "For an open stage: percent; omitted: the stage's default. Ignored for `won` and `lost`."
          },
          "lost_reason": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000,
                "minLength": 3
              },
              {
                "type": "null"
              }
            ],
            "title": "Lost Reason",
            "description": "Why it was lost (for `lost`)."
          },
          "on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "On",
            "description": "For `won` and `lost`: the day it closed; omitted: today."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 5000
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A note kept with the stage change."
          }
        },
        "type": "object",
        "required": [
          "stage"
        ],
        "title": "StageInput",
        "examples": [
          {
            "note": "Pricing agreed in principle",
            "stage": "negotiation"
          },
          {
            "on": "2026-10-04",
            "stage": "won"
          },
          {
            "lost_reason": "Chose a competitor on price",
            "stage": "lost"
          }
        ]
      },
      "StageTotal": {
        "properties": {
          "stage": {
            "type": "string",
            "enum": [
              "lead",
              "lost",
              "negotiation",
              "proposal",
              "qualified",
              "won"
            ],
            "title": "Stage",
            "description": "The stage."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency of the amounts."
          },
          "count": {
            "type": "integer",
            "title": "Count",
            "description": "How many opportunities."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Their expected value."
          },
          "weighted_amount": {
            "type": "string",
            "title": "Weighted Amount",
            "description": "Their value weighted by probability."
          }
        },
        "type": "object",
        "required": [
          "stage",
          "currency",
          "count",
          "amount",
          "weighted_amount"
        ],
        "title": "StageTotal"
      },
      "Statement": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the customer."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day the statement is as of."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of its PDF: the customer's, else the one spoken in its country."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/StatementItem"
            },
            "type": "array",
            "title": "Items",
            "description": "Open items, oldest due date first; credit notes are negative items."
          },
          "balances": {
            "items": {
              "$ref": "#/components/schemas/StatementBalance"
            },
            "type": "array",
            "title": "Balances",
            "description": "The balance and its age structure per currency, by currency code."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The entity's functional currency."
          },
          "totals_functional": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Totals Functional",
            "description": "The open amount per age band and `total` in the functional currency: the figures `reconciliation` ties to the ledger."
          },
          "reconciliation": {
            "$ref": "#/components/schemas/StatementReconciliation",
            "description": "The total against the customer's lines on the control account."
          },
          "issued": {
            "items": {
              "$ref": "#/components/schemas/StatementFile"
            },
            "type": "array",
            "title": "Issued",
            "description": "Statements of this customer and day that were archived (`POST .../issue`), oldest first, one per language."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "party_id",
          "party_code",
          "party",
          "as_of",
          "language",
          "items",
          "balances",
          "functional_currency",
          "totals_functional",
          "reconciliation",
          "issued"
        ],
        "title": "Statement",
        "description": "A customer's statement of account: the open items on a day.",
        "examples": [
          {
            "as_of": "2026-09-25",
            "balances": [
              {
                "balance": "681.00",
                "buckets": {
                  "1-30": "0.00",
                  "31-60": "0.00",
                  "61-90": "681.00",
                  "90+": "0.00",
                  "current": "0.00"
                },
                "currency": "CHF",
                "documents": 1,
                "overdue": "681.00",
                "overdue_documents": 1
              }
            ],
            "entity": "CH01",
            "functional_currency": "CHF",
            "issued": [
              {
                "file_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
                "filename": "statement-C-CH-2026-09-25-de.pdf",
                "issued_at": "2026-09-26T08:15:00Z",
                "issued_by": {
                  "id": "user:alice",
                  "name": "Alice",
                  "type": "human"
                },
                "language": "de",
                "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                "size": 4213
              }
            ],
            "items": [
              {
                "amount": "1081.00",
                "bucket": "61-90",
                "currency": "CHF",
                "days_overdue": 86,
                "document_date": "2026-06-01",
                "document_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "due_date": "2026-07-01",
                "kind": "sales_invoice",
                "number": "INV-2026-000001",
                "open": "681.00",
                "open_functional": "681.00",
                "reserved": false
              }
            ],
            "language": "de",
            "party": "Matter Treuhand AG",
            "party_code": "C-CH",
            "party_id": "0b7d1c3e-5a4e-4d0a-9f7a-2f6d1c1d8a11",
            "reconciliation": {
              "control_account": "1100",
              "control_balance": "681.00",
              "difference": "0.00",
              "pending_settlements": "0.00",
              "totals_functional": "681.00",
              "unexplained": "0.00",
              "unrealised_fx": "0.00"
            },
            "totals_functional": {
              "1-30": "0.00",
              "31-60": "0.00",
              "61-90": "681.00",
              "90+": "0.00",
              "current": "0.00",
              "total": "681.00"
            }
          }
        ]
      },
      "StatementBalance": {
        "properties": {
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency."
          },
          "balance": {
            "type": "string",
            "title": "Balance",
            "description": "The open amount in this currency; credit notes reduce it."
          },
          "overdue": {
            "type": "string",
            "title": "Overdue",
            "description": "The part of the balance that is past its due date (every band but `current`)."
          },
          "documents": {
            "type": "integer",
            "title": "Documents",
            "description": "How many items are listed in this currency."
          },
          "overdue_documents": {
            "type": "integer",
            "title": "Overdue Documents",
            "description": "How many of them are past their due date (`bucket` is not `current`)."
          },
          "buckets": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Buckets",
            "description": "The open amount per age band, every band present: `current`, `1-30`, `31-60`, `61-90`, `90+`. They add up to `balance`."
          }
        },
        "type": "object",
        "required": [
          "currency",
          "balance",
          "overdue",
          "documents",
          "overdue_documents",
          "buckets"
        ],
        "title": "StatementBalance",
        "description": "The open items of one currency: the balance and what is overdue, by age."
      },
      "StatementDate": {
        "properties": {
          "to_date": {
            "type": "string",
            "format": "date",
            "title": "To Date",
            "description": "Last day the statement covers."
          },
          "statement_ref": {
            "type": "string",
            "title": "Statement Ref",
            "description": "The statement's reference as given by the bank."
          },
          "closing_balance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closing Balance",
            "description": "Closing balance the bank reported; null when the file carries none (CSV)."
          }
        },
        "type": "object",
        "required": [
          "to_date",
          "statement_ref",
          "closing_balance"
        ],
        "title": "StatementDate"
      },
      "StatementFile": {
        "properties": {
          "file_id": {
            "type": "string",
            "format": "uuid",
            "title": "File Id",
            "description": "Id of the archived file (`document.id`)."
          },
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "File name, e.g. `statement-C-CH-2026-09-30-de.pdf`."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "Language the PDF was issued in."
          },
          "sha256": {
            "type": "string",
            "title": "Sha256",
            "description": "SHA-256 of the archived bytes."
          },
          "size": {
            "type": "integer",
            "title": "Size",
            "description": "Size in bytes."
          },
          "issued_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Issued By",
            "description": "Who issued it: type, id and name."
          },
          "issued_at": {
            "type": "string",
            "format": "date-time",
            "title": "Issued At",
            "description": "When it was archived."
          }
        },
        "type": "object",
        "required": [
          "file_id",
          "filename",
          "language",
          "sha256",
          "size",
          "issued_by",
          "issued_at"
        ],
        "title": "StatementFile",
        "description": "A statement kept in the document archive."
      },
      "StatementIssueInput": {
        "properties": {
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day the statement is as of, ISO 8601; not in the future.",
            "examples": [
              "2026-09-30"
            ]
          },
          "language": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "de",
                  "en",
                  "fr",
                  "it",
                  "sv"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Language",
            "description": "Language of the PDF; omitted: the customer's language. Another language is another archived file."
          }
        },
        "type": "object",
        "required": [
          "as_of"
        ],
        "title": "StatementIssueInput",
        "examples": [
          {
            "as_of": "2026-09-30"
          },
          {
            "as_of": "2026-09-30",
            "language": "fr"
          }
        ]
      },
      "StatementIssued": {
        "properties": {
          "file": {
            "$ref": "#/components/schemas/StatementFile",
            "description": "The archived PDF."
          },
          "created": {
            "type": "boolean",
            "title": "Created",
            "description": "True when this call archived the file; false when the statement of this customer, day and language was archived before and that file is returned (the archive wins: what the customer was told is not rewritten)."
          },
          "download": {
            "type": "string",
            "title": "Download",
            "description": "The path that returns the PDF (`GET .../statement?format=pdf`), which serves the archived file for this day and language."
          }
        },
        "type": "object",
        "required": [
          "file",
          "created",
          "download"
        ],
        "title": "StatementIssued",
        "description": "The result of issuing a statement.",
        "examples": [
          {
            "created": true,
            "download": "/v1/entities/CH01/customers/C-CH/statement?as_of=2026-09-25&format=pdf&language=de",
            "file": {
              "file_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
              "filename": "statement-C-CH-2026-09-25-de.pdf",
              "issued_at": "2026-09-26T08:15:00Z",
              "issued_by": {
                "id": "user:alice",
                "name": "Alice",
                "type": "human"
              },
              "language": "de",
              "sha256": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
              "size": 4213
            }
          }
        ]
      },
      "StatementItem": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice, bill or credit note; of the receipt or payment for an amount on account."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Document number, e.g. `INV-2026-000012`."
          },
          "kind": {
            "type": "string",
            "enum": [
              "payment_on_account",
              "purchase_bill",
              "purchase_credit_note",
              "sales_credit_note",
              "sales_invoice"
            ],
            "title": "Kind",
            "description": "`sales_invoice` or `sales_credit_note` on a customer's statement, `purchase_bill` or `purchase_credit_note` on a vendor's; `payment_on_account` on either: what is left on account of a receipt or payment, not yet applied (never overdue)."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "Document date."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "Due date."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the amounts."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Gross total, negative for a credit note."
          },
          "open": {
            "type": "string",
            "title": "Open",
            "description": "What is open on `as_of`, negative for a credit note: the total less the allocations dated on or before `as_of` (payments, credit notes, a cash discount taken)."
          },
          "open_functional": {
            "type": "string",
            "title": "Open Functional",
            "description": "The carrying amount the ledger holds for the item in the entity's functional currency on `as_of`, negative for a credit note.",
            "default": "0.00"
          },
          "reserved": {
            "type": "boolean",
            "title": "Reserved",
            "description": "True when payments waiting for approval reserve the whole open amount: `open` is zero, the ledger still carries the item.",
            "default": false
          },
          "days_overdue": {
            "type": "integer",
            "title": "Days Overdue",
            "description": "Days past the due date on `as_of`; 0 when not yet due."
          },
          "bucket": {
            "type": "string",
            "title": "Bucket",
            "description": "`current`, `1-30`, `31-60`, `61-90` or `90+` days overdue."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "kind",
          "document_date",
          "due_date",
          "currency",
          "amount",
          "open",
          "days_overdue",
          "bucket"
        ],
        "title": "StatementItem",
        "description": "One open item: an invoice or bill, or a credit note or a payment's amount on account as a\nnegative item."
      },
      "StatementLine": {
        "properties": {
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The group report line."
          },
          "labels": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Labels",
            "description": "Its label in `en`, `de`, `fr`, `it` and `sv`."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The amount in the reporting currency, positive in the line's own direction (an asset or revenue as a debit or credit balance respectively)."
          },
          "unmapped": {
            "type": "boolean",
            "title": "Unmapped",
            "description": "True for a line outside the group's vocabulary (a blocking exception names it)."
          }
        },
        "type": "object",
        "required": [
          "report_line",
          "labels",
          "amount",
          "unmapped"
        ],
        "title": "StatementLine"
      },
      "StatementOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Statement id; use it as the `statement` filter of the bank-lines list."
          },
          "statement_ref": {
            "type": "string",
            "title": "Statement Ref",
            "description": "The statement's reference as given by the bank; for a CSV file its account and dates, e.g. `CSV 1020 01.09.2026-30.09.2026`."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "GL bank account code the statement belongs to."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "Name of that GL account."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "IBAN of the bank account, when the file names it."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency code of the statement."
          },
          "format": {
            "type": "string",
            "title": "Format",
            "description": "File format it was imported from: `camt053`, `camt054`, `mt940` or `csv`."
          },
          "from_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "From Date",
            "description": "First day the statement covers, ISO 8601, when known."
          },
          "to_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "To Date",
            "description": "Last day the statement covers, ISO 8601, when known."
          },
          "opening_balance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opening Balance",
            "description": "Opening balance reported by the bank (decimal string); null if absent."
          },
          "closing_balance": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closing Balance",
            "description": "Closing balance reported by the bank; null for notifications."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the statement was imported (UTC timestamp)."
          },
          "lines": {
            "type": "integer",
            "title": "Lines",
            "description": "Number of lines of the statement."
          },
          "unmatched": {
            "type": "integer",
            "title": "Unmatched",
            "description": "Lines still waiting to be matched, posted or ignored."
          },
          "matched": {
            "type": "integer",
            "title": "Matched",
            "description": "Lines settled by a payment or an entry."
          },
          "ignored": {
            "type": "integer",
            "title": "Ignored",
            "description": "Lines marked as needing no booking."
          }
        },
        "type": "object",
        "required": [
          "id",
          "statement_ref",
          "account",
          "account_name",
          "iban",
          "currency",
          "format",
          "from_date",
          "to_date",
          "opening_balance",
          "closing_balance",
          "created_at",
          "lines",
          "unmatched",
          "matched",
          "ignored"
        ],
        "title": "StatementOut"
      },
      "StatementReconciliation": {
        "properties": {
          "control_account": {
            "type": "string",
            "title": "Control Account",
            "description": "Code of the receivables control account."
          },
          "control_balance": {
            "type": "string",
            "title": "Control Balance",
            "description": "The balance of this customer's lines on the control account in the ledger as of `as_of`, in the functional currency (what the customer owes us)."
          },
          "totals_functional": {
            "type": "string",
            "title": "Totals Functional",
            "description": "The statement's total in the functional currency: the sum of the items' `open_functional`, the carrying amounts the ledger holds."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "`control_balance` less `totals_functional`."
          },
          "unrealised_fx": {
            "type": "string",
            "title": "Unrealised Fx",
            "description": "Entries of source `fx` (period-end revaluations) on the customer's control lines up to `as_of` that no reversal has cancelled yet: they sit on the control account but on no document."
          },
          "pending_settlements": {
            "type": "string",
            "title": "Pending Settlements",
            "description": "A memo: the functional amount of payments and applications waiting for approval on the listed items (an application on both of its items). They reserve the open amount in the document currency but are not booked, so they are in neither `control_balance` nor `totals_functional`."
          },
          "unexplained": {
            "type": "string",
            "title": "Unexplained",
            "description": "`difference` less `unrealised_fx`: zero when the statement ties to the ledger; anything else is a posting on the control account that no document carries."
          }
        },
        "type": "object",
        "required": [
          "control_account",
          "control_balance",
          "totals_functional",
          "difference",
          "unrealised_fx",
          "pending_settlements",
          "unexplained"
        ],
        "title": "StatementReconciliation",
        "description": "The statement's total against the ledger: the customer's lines on the receivables control\naccount up to the day."
      },
      "StatusChange": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 3,
            "title": "Reason",
            "description": "Why the organization is suspended or reactivated, 3 to 500 characters; kept in the organization's audit trail and in the platform's security events."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "StatusChange",
        "examples": [
          {
            "reason": "Invoice 2026-114 unpaid after two reminders"
          }
        ]
      },
      "StatusInput": {
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "closed",
              "open",
              "waiting"
            ],
            "title": "Status",
            "description": "`open`, `waiting` (on the customer: the resolution clock stands still) or `closed`."
          },
          "resolution": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Resolution",
            "description": "How it was resolved (closing)."
          }
        },
        "type": "object",
        "required": [
          "status"
        ],
        "title": "StatusInput",
        "examples": [
          {
            "resolution": "Address corrected.",
            "status": "closed"
          }
        ]
      },
      "StatusReportResult": {
        "properties": {
          "message_id": {
            "type": "string",
            "title": "Message Id",
            "description": "The status report's own message id."
          },
          "payment_file": {
            "type": "string",
            "title": "Payment File",
            "description": "Message id of the payment file it reports on."
          },
          "rejected": {
            "items": {
              "$ref": "#/components/schemas/RejectedPayment"
            },
            "type": "array",
            "title": "Rejected",
            "description": "The payments the bank rejected, each with what the import did."
          },
          "accepted": {
            "type": "integer",
            "title": "Accepted",
            "description": "How many other payments of the file the report did not reject."
          }
        },
        "type": "object",
        "required": [
          "message_id",
          "payment_file",
          "rejected",
          "accepted"
        ],
        "title": "StatusReportResult"
      },
      "StayInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity that lets the rooms."
          },
          "room_type": {
            "type": "string",
            "title": "Room Type",
            "description": "Product code (or id) of the room type."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Code (or id) of the customer who pays: the invoice goes to it, in its currency and at its prices."
          },
          "arrival": {
            "type": "string",
            "format": "date",
            "title": "Arrival",
            "description": "The day the guests arrive: the first night."
          },
          "departure": {
            "type": "string",
            "format": "date",
            "title": "Departure",
            "description": "The day they leave, after the last night (at most a year after arrival)."
          },
          "rooms": {
            "type": "integer",
            "maximum": 1000.0,
            "minimum": 1.0,
            "title": "Rooms",
            "description": "Rooms of the type; default 1.",
            "default": 1
          },
          "guests": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 50000.0,
                "minimum": 1.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Guests",
            "description": "How many guests; default one a room. At most the rooms times what a room sleeps."
          },
          "guest_name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Guest Name",
            "description": "The guest's name, on the invoice line."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 100
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The customer's reference, e.g. its order number: the invoice's (BT-13)."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "room_type",
          "customer",
          "arrival",
          "departure"
        ],
        "title": "StayInput",
        "examples": [
          {
            "arrival": "2026-11-15",
            "customer": "C-CH",
            "departure": "2026-11-17",
            "entity": "CH01",
            "guest_name": "Anna Muster",
            "room_type": "DBL"
          }
        ]
      },
      "StayInvoice": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the sales invoice (`GET /v1/documents/{id}`)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number; null while it is a draft."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft`, `pending_approval`, `posted` or `rejected`."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Its total in `currency`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "status",
          "total",
          "currency"
        ],
        "title": "StayInvoice"
      },
      "StayOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the stay."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Stay number, gap-free per entity and year (ST-...)."
          },
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Id of the room type's product."
          },
          "room_type": {
            "type": "string",
            "title": "Room Type",
            "description": "Product code of the room type."
          },
          "room_type_name": {
            "type": "string",
            "title": "Room Type Name",
            "description": "Its name."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Customer name."
          },
          "guest_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Guest Name",
            "description": "The guest's name."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "The customer's reference."
          },
          "arrival": {
            "type": "string",
            "format": "date",
            "title": "Arrival",
            "description": "Arrival day."
          },
          "departure": {
            "type": "string",
            "format": "date",
            "title": "Departure",
            "description": "Departure day (the day they left, once out)."
          },
          "rooms": {
            "type": "integer",
            "title": "Rooms",
            "description": "Rooms."
          },
          "guests": {
            "type": "integer",
            "title": "Guests",
            "description": "Guests."
          },
          "room": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Room",
            "description": "The rooms given at check-in."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 code of the prices."
          },
          "nights": {
            "items": {
              "$ref": "#/components/schemas/NightPrice"
            },
            "type": "array",
            "title": "Nights",
            "description": "Each night with its price."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Net total of the nights (times the rooms)."
          },
          "status": {
            "type": "string",
            "enum": [
              "cancelled",
              "checked_in",
              "checked_out",
              "reserved"
            ],
            "title": "Status",
            "description": "`reserved`, `checked_in`, `checked_out` or `cancelled`."
          },
          "booking": {
            "type": "string",
            "title": "Booking",
            "description": "Number of the booking of its rooms (`BK-...`)."
          },
          "invoice": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StayInvoice"
              },
              {
                "type": "null"
              }
            ],
            "description": "The invoice of the stay, once out."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who reserved it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "checked_in_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checked In By",
            "description": "Who checked the guests in."
          },
          "checked_in_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checked In At",
            "description": "When (UTC)."
          },
          "checked_out_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checked Out By",
            "description": "Who checked them out."
          },
          "checked_out_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Checked Out At",
            "description": "When (UTC)."
          },
          "cancelled_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancelled By",
            "description": "Who cancelled it."
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancelled At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "product_id",
          "room_type",
          "room_type_name",
          "customer",
          "customer_name",
          "guest_name",
          "reference",
          "arrival",
          "departure",
          "rooms",
          "guests",
          "room",
          "currency",
          "nights",
          "total",
          "status",
          "booking",
          "invoice",
          "created_by",
          "created_at",
          "checked_in_by",
          "checked_in_at",
          "checked_out_by",
          "checked_out_at",
          "cancelled_by",
          "cancelled_at"
        ],
        "title": "StayOut"
      },
      "StepDay": {
        "properties": {
          "step": {
            "type": "string",
            "enum": [
              "checklist",
              "close",
              "close_review",
              "deferred_tax",
              "depreciation",
              "forecast_roll",
              "fx_revaluation",
              "recurring_invoices"
            ],
            "title": "Step",
            "description": "The step."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the step is."
          },
          "due_day": {
            "type": "integer",
            "title": "Due Day",
            "description": "The working day after the period end it is due on."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who does the step; null: the close owner."
          }
        },
        "type": "object",
        "required": [
          "step",
          "title",
          "due_day"
        ],
        "title": "StepDay"
      },
      "StepStatus": {
        "properties": {
          "step": {
            "type": "string",
            "enum": [
              "checklist",
              "close",
              "close_review",
              "deferred_tax",
              "depreciation",
              "forecast_roll",
              "fx_revaluation",
              "recurring_invoices"
            ],
            "title": "Step",
            "description": "The step."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What the step is."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "The day it is due."
          },
          "status": {
            "type": "string",
            "enum": [
              "done",
              "n/a",
              "open",
              "overdue"
            ],
            "title": "Status",
            "description": "`done`, `open` (not done, not yet due), `overdue` (not done and its due date has passed) or `n/a` (nothing to do this period)."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "Why, in words (the check's result where a check decides it)."
          },
          "reason": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Reason"
              },
              {
                "type": "null"
              }
            ],
            "description": "`detail` by a stable code, for the screens to word in the person's language (`closeTracker.result`, or the deciding check's `periodClose.result`); null where the check gave no code."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who does the step: its own owner, else the close owner."
          },
          "done_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Done By",
            "description": "Who did it (actor object), where a record says so: the run of a period-end step, the close memo, the close, the latest forecast version; null otherwise."
          },
          "done_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Done At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "step",
          "title",
          "due_date",
          "status",
          "detail"
        ],
        "title": "StepStatus"
      },
      "StepUpDone": {
        "properties": {
          "passkey_at": {
            "type": "string",
            "format": "date-time",
            "title": "Passkey At",
            "description": "When the passkey was touched (ISO 8601, UTC): steps that ask for a fresh touch work for five minutes from then."
          }
        },
        "type": "object",
        "required": [
          "passkey_at"
        ],
        "title": "StepUpDone"
      },
      "StockCountInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity."
          },
          "warehouse": {
            "type": "string",
            "title": "Warehouse",
            "description": "Warehouse counted (code or id)."
          },
          "count_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Count Date",
            "description": "The day of the count; omitted: today. Not in the future."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A note."
          },
          "items": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array",
                "maxItems": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Items",
            "description": "The items to count (product codes or ids); omitted: every active stock item of the entity."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "warehouse"
        ],
        "title": "StockCountInput",
        "examples": [
          {
            "count_date": "2026-08-31",
            "entity": "CH01",
            "warehouse": "ZRH"
          }
        ]
      },
      "StockCountLineOut": {
        "properties": {
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code."
          },
          "item_name": {
            "type": "string",
            "title": "Item Name",
            "description": "Product name."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "Unit."
          },
          "book_quantity": {
            "type": "string",
            "title": "Book Quantity",
            "description": "What the books hold in the warehouse: today while the count is open, what it was posted against once posted."
          },
          "counted_quantity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counted Quantity",
            "description": "What was counted; null: not counted."
          },
          "difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Difference",
            "description": "Counted less book; null while not counted."
          },
          "value_difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value Difference",
            "description": "The difference at the moving average (once posted: what was booked)."
          },
          "counted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counted By",
            "description": "Who entered the count."
          }
        },
        "type": "object",
        "required": [
          "item",
          "item_name",
          "unit",
          "book_quantity",
          "counted_quantity",
          "difference",
          "value_difference",
          "counted_by"
        ],
        "title": "StockCountLineOut"
      },
      "StockCountOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Count id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Number, e.g. `CNT-2026-000003`."
          },
          "warehouse": {
            "type": "string",
            "title": "Warehouse",
            "description": "Warehouse code."
          },
          "warehouse_name": {
            "type": "string",
            "title": "Warehouse Name",
            "description": "Warehouse name."
          },
          "count_date": {
            "type": "string",
            "format": "date",
            "title": "Count Date",
            "description": "Day of the count."
          },
          "status": {
            "type": "string",
            "enum": [
              "cancelled",
              "open",
              "posted"
            ],
            "title": "Status",
            "description": "`open`, `posted` or `cancelled`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency of the values."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Note."
          },
          "counted": {
            "type": "integer",
            "title": "Counted",
            "description": "Lines counted so far."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/StockCountLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The items, by code."
          },
          "posting_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Id",
            "description": "The posting of its differences."
          },
          "posting_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Number",
            "description": "Number of that posting."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who opened it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "decided_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided By",
            "description": "Who posted or cancelled it."
          },
          "decided_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Decided At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "warehouse",
          "warehouse_name",
          "count_date",
          "status",
          "currency",
          "note",
          "counted",
          "lines",
          "posting_id",
          "posting_number",
          "created_by",
          "created_at",
          "decided_by",
          "decided_at"
        ],
        "title": "StockCountOut"
      },
      "StockItemInput": {
        "properties": {
          "product": {
            "type": "string",
            "title": "Product",
            "description": "Code (or id) of the product to keep in stock: goods sold per unit."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code (or id) of the product's entity; needed with a code."
          },
          "inventory_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inventory Account",
            "description": "Account (code or id) its stock is booked to: a control account on the inventories line; omitted: the entity's inventory account (role `inventory`)."
          },
          "cogs_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cogs Account",
            "description": "Expense account (code or id) its cost of goods sold is booked to; omitted: the entity's account of the role `cogs`."
          }
        },
        "type": "object",
        "required": [
          "product"
        ],
        "title": "StockItemInput",
        "examples": [
          {
            "product": "SCANNER"
          },
          {
            "cogs_account": "4200",
            "product": "LABELPRN"
          }
        ]
      },
      "StockItemOut": {
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Id of the product (and of the stock item)."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Product code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Product name."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "The unit its quantities are in."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether the product is still sold."
          },
          "inventory_account": {
            "type": "string",
            "title": "Inventory Account",
            "description": "Code of its inventory account."
          },
          "cogs_account": {
            "type": "string",
            "title": "Cogs Account",
            "description": "Code of its cost of goods sold account."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency: what values are in."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity in stock (all warehouses)."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "Value of the stock, in the functional currency."
          },
          "average_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Average Cost",
            "description": "Moving average cost of one unit (value / quantity, six decimals); null when nothing is in stock."
          },
          "levels": {
            "items": {
              "$ref": "#/components/schemas/StockLevelOut"
            },
            "type": "array",
            "title": "Levels",
            "description": "Quantity per warehouse that holds some."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who started keeping it in stock."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "product_id",
          "entity",
          "code",
          "name",
          "unit",
          "active",
          "inventory_account",
          "cogs_account",
          "currency",
          "quantity",
          "value",
          "average_cost",
          "levels",
          "created_by",
          "created_at"
        ],
        "title": "StockItemOut"
      },
      "StockItemUpdate": {
        "properties": {
          "inventory_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Inventory Account",
            "description": "New inventory account; only while nothing is in stock."
          },
          "cogs_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cogs Account",
            "description": "New cost of goods sold account."
          }
        },
        "type": "object",
        "title": "StockItemUpdate",
        "examples": [
          {
            "cogs_account": "4200"
          }
        ]
      },
      "StockLevelOut": {
        "properties": {
          "warehouse": {
            "type": "string",
            "title": "Warehouse",
            "description": "Warehouse code."
          },
          "warehouse_name": {
            "type": "string",
            "title": "Warehouse Name",
            "description": "Warehouse name."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity in the warehouse."
          }
        },
        "type": "object",
        "required": [
          "warehouse",
          "warehouse_name",
          "quantity"
        ],
        "title": "StockLevelOut"
      },
      "StockMovementOut": {
        "properties": {
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Line number."
          },
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code."
          },
          "item_name": {
            "type": "string",
            "title": "Item Name",
            "description": "Product name."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "Unit."
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "Warehouse code; null for a revaluation."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "In (positive) or out (negative)."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "Value in the functional currency, with the same sign."
          },
          "unit_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Cost",
            "description": "Value / quantity (six decimals); null for a revaluation or no quantity."
          },
          "offset_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Offset Account",
            "description": "Code of the account booked against."
          }
        },
        "type": "object",
        "required": [
          "line_no",
          "item",
          "item_name",
          "unit",
          "warehouse",
          "quantity",
          "value",
          "unit_cost",
          "offset_account"
        ],
        "title": "StockMovementOut"
      },
      "StockPostingOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Posting id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Number, e.g. `STK-2026-000012`."
          },
          "kind": {
            "type": "string",
            "enum": [
              "adjustment",
              "count",
              "delivery",
              "receipt",
              "return",
              "revaluation",
              "transfer"
            ],
            "title": "Kind",
            "description": "What happened."
          },
          "posting_date": {
            "type": "string",
            "format": "date",
            "title": "Posting Date",
            "description": "The day the stock changed."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_approval",
              "posted",
              "rejected"
            ],
            "title": "Status",
            "description": "`posted`, or `pending_approval` (its entry waits for a person; the stock has not changed yet), or `rejected`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The functional currency of the values."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "Total value of its lines (net, with signs)."
          },
          "journal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Id",
            "description": "Its entry; null for a transfer."
          },
          "journal_entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Journal Entry Number",
            "description": "Number of its entry, once posted."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why, or a note."
          },
          "source_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Type",
            "description": "What it is for (a count, a receipt, ...)."
          },
          "source_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Id",
            "description": "Id of that document."
          },
          "source_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Source Number",
            "description": "Number of that document."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/StockMovementOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The movements."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who recorded it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "kind",
          "posting_date",
          "status",
          "currency",
          "value",
          "journal_entry_id",
          "journal_entry_number",
          "note",
          "source_type",
          "source_id",
          "source_number",
          "lines",
          "created_by",
          "created_at"
        ],
        "title": "StockPostingOut"
      },
      "Subdivision": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "ISO 3166-2 code, e.g. `US-NY`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Its name, e.g. `New York`."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name"
        ],
        "title": "Subdivision"
      },
      "SubmitOut": {
        "properties": {
          "result": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "What the approval policy decided and where the entry stands now."
          },
          "entry": {
            "$ref": "#/components/schemas/JournalEntryOut",
            "description": "The journal entry in its new state, with its lines."
          }
        },
        "type": "object",
        "required": [
          "result",
          "entry"
        ],
        "title": "SubmitOut"
      },
      "SubmitResult": {
        "properties": {
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "Id (uuid) of the journal entry."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`posted`, `pending_approval` or `draft` (created without submitting)."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "The entry number once posted; null otherwise."
          },
          "policy": {
            "$ref": "#/components/schemas/PolicyResult",
            "description": "The decision of the approval policy for this entry and caller."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "Id (uuid) of the approval request when the entry waits for approval (`POST /v1/approvals/{approval_id}/approve`); else null."
          },
          "reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reason",
            "description": "Why the entry waits for approval, in words: the policy's reason, or why a second person must see it (a bill that quotes a purchase order that does not exist), or both; null when it posted."
          }
        },
        "type": "object",
        "required": [
          "entry_id",
          "status",
          "number",
          "policy"
        ],
        "title": "SubmitResult"
      },
      "SubscriptionActivationOut": {
        "properties": {
          "subscription": {
            "$ref": "#/components/schemas/SubscriptionOut",
            "description": "The subscription after the request."
          },
          "decision": {
            "type": "string",
            "enum": [
              "allow",
              "require_approval"
            ],
            "title": "Decision",
            "description": "`allow`: active now; `require_approval`: a second person decides (`POST /v1/approvals/{approval_id}/approve`)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request, when one is open."
          }
        },
        "type": "object",
        "required": [
          "subscription",
          "decision",
          "approval_id"
        ],
        "title": "SubscriptionActivationOut"
      },
      "SubscriptionCancelInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why it is cancelled."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "SubscriptionCancelInput",
        "examples": [
          {
            "reason": "The customer chose another plan"
          }
        ]
      },
      "SubscriptionInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Code (or id) of the customer."
          },
          "title": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Title",
            "description": "What is subscribed."
          },
          "currency": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{3}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Currency",
            "description": "ISO 4217 code of the currency it bills in: its prices, invoices, credit notes and revenue contract are in it. Default: the won opportunity's currency, else the customer's, else the entity's functional currency. Each product needs a list price (or the line a `unit_price`) and an SSP in it: a price is never converted."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first day of the first term."
          },
          "term_months": {
            "type": "integer",
            "maximum": 60.0,
            "minimum": 1.0,
            "title": "Term Months",
            "description": "The committed term in months: a whole number of billing periods."
          },
          "billing_frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Billing Frequency",
            "description": "How often it is invoiced; the periods are counted from the term start.",
            "default": "monthly"
          },
          "billing_timing": {
            "type": "string",
            "enum": [
              "advance",
              "arrears"
            ],
            "title": "Billing Timing",
            "description": "`advance` (invoiced on a period's first day) or `arrears` (on the day after its last).",
            "default": "advance"
          },
          "auto_renew": {
            "type": "boolean",
            "title": "Auto Renew",
            "description": "Whether the approved terms renew themselves: the first billing run after the term's last day starts the next term, as long and with its own revenue contract, at the prices in force raised by `renewal_uplift_percent`. Without it a person asks for a renewal (`POST .../amendments`, `kind` `renew`) or the subscription ends.",
            "default": false
          },
          "renewal_notice_days": {
            "type": "integer",
            "maximum": 365.0,
            "minimum": 0.0,
            "title": "Renewal Notice Days",
            "description": "Days before the term's last day the renewal is due (`renewal_status` `due`).",
            "default": 30
          },
          "renewal_uplift_percent": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,4}0*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Renewal Uplift Percent",
            "description": "By how much a renewal raises each line's price (each price rounded to the currency's minor unit); none keeps the prices. At most 4 decimals."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 365.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Days to pay an invoice; default the customer's."
          },
          "auto_submit": {
            "type": "boolean",
            "title": "Auto Submit",
            "description": "True: the system submits each invoice under the approved terms; false: the run leaves drafts for a person.",
            "default": false
          },
          "opportunity": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity",
            "description": "The won opportunity it came from (`GET /v1/opportunities`)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/SubscriptionLineInput"
            },
            "type": "array",
            "maxItems": 50,
            "minItems": 1,
            "title": "Lines",
            "description": "What is sold."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "party",
          "title",
          "start_date",
          "term_months",
          "lines"
        ],
        "title": "SubscriptionInput",
        "examples": [
          {
            "auto_renew": false,
            "billing_frequency": "monthly",
            "billing_timing": "advance",
            "entity": "CH01",
            "lines": [
              {
                "product": "PLATFORM",
                "quantity": "10"
              }
            ],
            "party": "C-CH",
            "start_date": "2027-01-01",
            "term_months": 12,
            "title": "Platform, 10 seats"
          }
        ]
      },
      "SubscriptionInvoiceOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Row id."
          },
          "period_start": {
            "type": "string",
            "format": "date",
            "title": "Period Start",
            "description": "The billing period's first day."
          },
          "period_end": {
            "type": "string",
            "format": "date",
            "title": "Period End",
            "description": "Its last day."
          },
          "kind": {
            "type": "string",
            "enum": [
              "credit",
              "period"
            ],
            "title": "Kind",
            "description": "`period`: the invoice of a billing period; `credit`: the credit note an amendment made for the unused part of a billed period."
          },
          "amendment_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amendment Id",
            "description": "`credit`: the amendment that made it."
          },
          "status": {
            "type": "string",
            "enum": [
              "drafted",
              "failed",
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "What the run (or amendment) did: `drafted` (left for a person), `posted`, `pending_approval` or `failed`. It is not updated afterwards: the invoice's own status is `document_status`."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The invoice or credit note; null when it failed."
          },
          "document_status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Status",
            "description": "The invoice's status now (`draft`, `pending_approval`, `posted`, `rejected` or `void`; a voided draft is made again by the next run); null when it failed."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why a failed attempt failed."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When."
          }
        },
        "type": "object",
        "required": [
          "id",
          "period_start",
          "period_end",
          "kind",
          "status",
          "document_id",
          "error",
          "created_at"
        ],
        "title": "SubscriptionInvoiceOut"
      },
      "SubscriptionLineInput": {
        "properties": {
          "product": {
            "type": "string",
            "title": "Product",
            "description": "Code (or id) of a recurring product of the entity (`GET /v1/products`). It gives the description, the revenue account, the VAT supply and rate type, the price in force on the start day when `unit_price` is omitted, and the standalone selling price of the term's revenue contract."
          },
          "description": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "Default: the product's name."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,12}|(?=[\\d.]{1,19}0*$)\\d{0,12}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Quantity",
            "description": "How many units (seats), at most 6 decimals.",
            "default": "1"
          },
          "unit_price": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              },
              {
                "type": "null"
              }
            ],
            "title": "Unit Price",
            "description": "Net price of one unit per the product's price period (month or year), at most 6 decimals; default: the product's list price in force on the start day."
          },
          "discount_percent": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMaximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d{0,4}0*$"
              }
            ],
            "title": "Discount Percent",
            "description": "Discount on the price, in percent, at most 4 decimals.",
            "default": "0"
          },
          "revenue_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Revenue Account",
            "description": "Revenue account (code or id); default the product's."
          }
        },
        "type": "object",
        "required": [
          "product"
        ],
        "title": "SubscriptionLineInput"
      },
      "SubscriptionLineOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Line id."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Position, from 1."
          },
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "The product."
          },
          "product_code": {
            "type": "string",
            "title": "Product Code",
            "description": "Its code."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What is sold."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "How many units."
          },
          "unit_price": {
            "type": "string",
            "title": "Unit Price",
            "description": "Net price of one unit per `price_period`."
          },
          "price_period": {
            "type": "string",
            "enum": [
              "month",
              "year"
            ],
            "title": "Price Period",
            "description": "`month` or `year`."
          },
          "discount_percent": {
            "type": "string",
            "title": "Discount Percent",
            "description": "Discount in percent."
          },
          "monthly_amount": {
            "type": "string",
            "title": "Monthly Amount",
            "description": "What a month of service costs, rounded to the currency (quantity times the monthly price, less the discount)."
          },
          "revenue_account": {
            "type": "string",
            "title": "Revenue Account",
            "description": "Code of the revenue account."
          },
          "valid_from": {
            "type": "string",
            "format": "date",
            "title": "Valid From",
            "description": "The first day it applies."
          },
          "valid_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid To",
            "description": "The last day it applies; null while open."
          },
          "obligation_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Obligation Id",
            "description": "Its performance obligation in the current term's revenue contract; null before the subscription is active."
          }
        },
        "type": "object",
        "required": [
          "id",
          "line_no",
          "product_id",
          "product_code",
          "description",
          "quantity",
          "unit_price",
          "price_period",
          "discount_percent",
          "monthly_amount",
          "revenue_account",
          "valid_from",
          "valid_to",
          "obligation_id"
        ],
        "title": "SubscriptionLineOut"
      },
      "SubscriptionOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Subscription id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "`SUB-000001`, per entity."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "The customer's id."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "The customer's code."
          },
          "party_name": {
            "type": "string",
            "title": "Party Name",
            "description": "The customer's name."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What is subscribed."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The currency it bills in (prices, invoices, credit notes, its revenue contracts); revenue is booked in the entity's functional currency (ADR-0050)."
          },
          "start_date": {
            "type": "string",
            "format": "date",
            "title": "Start Date",
            "description": "The first day of the first term."
          },
          "term_months": {
            "type": "integer",
            "title": "Term Months",
            "description": "The committed term in months."
          },
          "current_term_start": {
            "type": "string",
            "format": "date",
            "title": "Current Term Start",
            "description": "The current term's first day."
          },
          "current_term_end": {
            "type": "string",
            "format": "date",
            "title": "Current Term End",
            "description": "The current term's last day."
          },
          "billing_frequency": {
            "type": "string",
            "enum": [
              "monthly",
              "quarterly",
              "yearly"
            ],
            "title": "Billing Frequency",
            "description": "How often it is invoiced."
          },
          "billing_timing": {
            "type": "string",
            "enum": [
              "advance",
              "arrears"
            ],
            "title": "Billing Timing",
            "description": "`advance` or `arrears`."
          },
          "auto_renew": {
            "type": "boolean",
            "title": "Auto Renew",
            "description": "Whether the approved terms renew themselves."
          },
          "renewal_notice_days": {
            "type": "integer",
            "title": "Renewal Notice Days",
            "description": "Days before the term end a renewal is due."
          },
          "renewal_uplift_percent": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Renewal Uplift Percent",
            "description": "What a renewal adds to the prices."
          },
          "payment_terms_days": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Terms Days",
            "description": "Days to pay; null: the customer's."
          },
          "auto_submit": {
            "type": "boolean",
            "title": "Auto Submit",
            "description": "Whether the system submits each invoice."
          },
          "term_amount": {
            "type": "string",
            "title": "Term Amount",
            "description": "What the current term costs, net of VAT: the transaction price of its revenue contract (less, once the term is ended early)."
          },
          "ends_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Ends On",
            "description": "The last day of service of a term ended early (an applied `cancel` amendment): nothing after it is billed; null otherwise."
          },
          "changes_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Changes On",
            "description": "The first day of new lines an applied `change` amendment approved, until they are in force (the billing run moves to them once the current lines are billed through the day before); null otherwise."
          },
          "terms_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms From",
            "description": "The first day of the lines in force: the current term's, or the day a `change` started them."
          },
          "next_bill": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Next Bill",
            "description": "The first day of the next billing period to invoice; null unless active."
          },
          "term_no": {
            "type": "integer",
            "title": "Term No",
            "description": "The current term's number, the first being 1.",
            "default": 1
          },
          "renewal_status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "approved",
                  "auto",
                  "due",
                  "ends",
                  "requested",
                  "upcoming"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Renewal Status",
            "description": "An active subscription's next term: `auto` (its terms renew it), `approved` (a second person approved its renewal), `requested` (a renewal waits for approval), `due` (the notice day has come and nothing renews it), `upcoming` (not yet due), `ends` (it ends on `ends_on`); for a subscription the billing run ended with its term (not early), `due` or `requested`: it may still be renewed, and the approval starts the next term at once; null otherwise."
          },
          "renewal_due_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Renewal Due On",
            "description": "The day the renewal is due: `renewal_notice_days` before the term's last day."
          },
          "renews_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Renews On",
            "description": "The next term's first day, when it renews (`auto`, `approved`)."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "cancelled",
              "draft",
              "ended",
              "pending_approval"
            ],
            "title": "Status",
            "description": "The status."
          },
          "terms_digest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Terms Digest",
            "description": "SHA-256 of the approved terms."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved the terms."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When."
          },
          "contract_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contract Id",
            "description": "The current term's revenue contract."
          },
          "contract_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Contract Number",
            "description": "Its number."
          },
          "opportunity_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Opportunity Id",
            "description": "The opportunity it came from."
          },
          "renewal_deal_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Renewal Deal Id",
            "description": "The renewal deal of the current term, opened when its renewal fell due."
          },
          "renewal_deal_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Renewal Deal Number",
            "description": "Its number."
          },
          "cancel_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancel Reason",
            "description": "Why it was cancelled."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/SubscriptionLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "What is sold."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "number",
          "party_id",
          "party_code",
          "party_name",
          "title",
          "currency",
          "start_date",
          "term_months",
          "current_term_start",
          "current_term_end",
          "billing_frequency",
          "billing_timing",
          "auto_renew",
          "renewal_notice_days",
          "renewal_uplift_percent",
          "payment_terms_days",
          "auto_submit",
          "term_amount",
          "next_bill",
          "status",
          "terms_digest",
          "approved_by",
          "approved_at",
          "contract_id",
          "contract_number",
          "opportunity_id",
          "cancel_reason",
          "lines",
          "created_by",
          "created_at"
        ],
        "title": "SubscriptionOut",
        "examples": [
          {
            "auto_renew": false,
            "auto_submit": false,
            "billing_frequency": "monthly",
            "billing_timing": "advance",
            "created_at": "2026-10-05T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "currency": "CHF",
            "current_term_end": "2027-12-31",
            "current_term_start": "2027-01-01",
            "entity": "CH01",
            "id": "5a6b7c8d-9e0f-4a1b-8c2d-3e4f5a6b7c8d",
            "lines": [],
            "number": "SUB-000001",
            "party_code": "C-CH",
            "party_id": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
            "party_name": "Zürich Kunde AG",
            "renewal_notice_days": 30,
            "start_date": "2027-01-01",
            "status": "draft",
            "term_amount": "6000.00",
            "term_months": 12,
            "title": "Platform, 10 seats"
          }
        ]
      },
      "SubscriptionRef": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The subscription's id."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "The subscription's number, such as `SUB-000004`."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number"
        ],
        "title": "SubscriptionRef"
      },
      "SubscriptionRunInput": {
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "title": "Through",
            "description": "Bill the periods whose invoice date is on or before this day (inclusive). It may not lie more than a day after the server's date (UTC)."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Only this entity (code or id)."
          },
          "subscription": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subscription",
            "description": "Only this subscription (it must be active)."
          }
        },
        "type": "object",
        "required": [
          "through"
        ],
        "title": "SubscriptionRunInput",
        "examples": [
          {
            "entity": "CH01",
            "through": "2027-01-31"
          }
        ]
      },
      "SubscriptionRunItem": {
        "properties": {
          "subscription_id": {
            "type": "string",
            "format": "uuid",
            "title": "Subscription Id",
            "description": "The subscription."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number."
          },
          "period_start": {
            "type": "string",
            "format": "date",
            "title": "Period Start",
            "description": "The billing period's first day."
          },
          "period_end": {
            "type": "string",
            "format": "date",
            "title": "Period End",
            "description": "Its last day."
          },
          "invoice_date": {
            "type": "string",
            "format": "date",
            "title": "Invoice Date",
            "description": "The invoice's date."
          },
          "status": {
            "type": "string",
            "enum": [
              "drafted",
              "failed",
              "pending_approval",
              "posted"
            ],
            "title": "Status",
            "description": "`drafted` (left for a person to submit), `posted`, `pending_approval` or `failed` (nothing was made; `error` says why, and the next run tries again)."
          },
          "document_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Id",
            "description": "The invoice; null when it failed."
          },
          "net": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Net",
            "description": "Its net amount; null when it failed."
          },
          "error": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Error",
            "description": "Why it failed; null otherwise."
          }
        },
        "type": "object",
        "required": [
          "subscription_id",
          "number",
          "period_start",
          "period_end",
          "invoice_date",
          "status",
          "document_id",
          "net",
          "error"
        ],
        "title": "SubscriptionRunItem"
      },
      "SubscriptionRunResult": {
        "properties": {
          "through": {
            "type": "string",
            "format": "date",
            "title": "Through",
            "description": "The day billed through."
          },
          "made": {
            "type": "integer",
            "title": "Made",
            "description": "Invoices made."
          },
          "failed": {
            "type": "integer",
            "title": "Failed",
            "description": "Periods that failed (tried again by the next run)."
          },
          "items": {
            "items": {
              "$ref": "#/components/schemas/SubscriptionRunItem"
            },
            "type": "array",
            "title": "Items",
            "description": "What was made, in order."
          },
          "more_due": {
            "type": "boolean",
            "title": "More Due",
            "description": "True when a run stopped early (at most a year of periods per subscription) and more is due: run again."
          }
        },
        "type": "object",
        "required": [
          "through",
          "made",
          "failed",
          "items",
          "more_due"
        ],
        "title": "SubscriptionRunResult"
      },
      "SuggestionOut": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Pass it to `POST /v1/roles/suggestions/{id}/apply`."
          },
          "user_id": {
            "type": "string",
            "format": "uuid",
            "title": "User Id",
            "description": "Id of the person."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Their name; null when they gave none."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The address they sign in with."
          },
          "kind": {
            "type": "string",
            "enum": [
              "close_area",
              "end_access",
              "narrow_areas",
              "remove_right"
            ],
            "title": "Kind",
            "description": "`remove_right` (a right unused), `close_area` (an area unused), `narrow_areas` (a person who opens every area used only some) or `end_access` (nothing used and no sign-in)."
          },
          "right": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Right",
            "description": "`remove_right`: the right."
          },
          "areas": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Areas",
            "description": "`close_area`: the area; `narrow_areas`: the areas kept."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why, in plain words."
          }
        },
        "type": "object",
        "required": [
          "id",
          "user_id",
          "name",
          "email",
          "kind",
          "reason"
        ],
        "title": "SuggestionOut"
      },
      "SuggestionsOut": {
        "properties": {
          "counting_since": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counting Since",
            "description": "The first day use was counted in this organization; suggestions come once a right was held and watched for the 90 days they look back."
          },
          "days": {
            "type": "integer",
            "title": "Days",
            "description": "How many days without use make a suggestion (90)."
          },
          "suggestions": {
            "items": {
              "$ref": "#/components/schemas/SuggestionOut"
            },
            "type": "array",
            "title": "Suggestions",
            "description": "What to take away, person by person."
          }
        },
        "type": "object",
        "required": [
          "counting_since",
          "days",
          "suggestions"
        ],
        "title": "SuggestionsOut"
      },
      "Summary": {
        "properties": {
          "needed": {
            "type": "integer",
            "title": "Needed",
            "description": "Number of data points the organization needs."
          },
          "ok": {
            "type": "integer",
            "title": "Ok",
            "description": "Needed data points with state `ok`."
          },
          "stale": {
            "type": "integer",
            "title": "Stale",
            "description": "Needed data points with state `stale`."
          },
          "no_data": {
            "type": "integer",
            "title": "No Data",
            "description": "Needed data points with state `no_data`."
          },
          "error": {
            "type": "integer",
            "title": "Error",
            "description": "Needed data points with state `error`."
          },
          "gap": {
            "type": "integer",
            "title": "Gap",
            "description": "Needed data points no registered authority covers."
          },
          "unknown": {
            "type": "integer",
            "title": "Unknown",
            "description": "Needed data points whose state is not known."
          },
          "available": {
            "type": "integer",
            "title": "Available",
            "description": "Data points in the register."
          }
        },
        "type": "object",
        "required": [
          "needed",
          "ok",
          "stale",
          "no_data",
          "error",
          "gap",
          "unknown",
          "available"
        ],
        "title": "Summary"
      },
      "SyncOut": {
        "properties": {
          "emails": {
            "type": "integer",
            "title": "Emails",
            "description": "E-mails newly logged on deals and customers."
          },
          "meetings": {
            "type": "integer",
            "title": "Meetings",
            "description": "Meetings newly logged."
          },
          "read_emails": {
            "type": "integer",
            "title": "Read Emails",
            "description": "E-mails read from the mailbox (matched or not)."
          },
          "read_meetings": {
            "type": "integer",
            "title": "Read Meetings",
            "description": "Meetings read from the calendar (matched or not)."
          },
          "cases": {
            "type": "integer",
            "title": "Cases",
            "description": "E-mails to or from a support queue's inbox newly put on a case.",
            "default": 0
          },
          "mailbox": {
            "$ref": "#/components/schemas/MailboxStatus",
            "description": "The link after reading."
          }
        },
        "type": "object",
        "required": [
          "emails",
          "meetings",
          "read_emails",
          "read_meetings",
          "mailbox"
        ],
        "title": "SyncOut"
      },
      "TaskInput": {
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Title",
            "description": "What is to be done."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "Who does it (`GET /v1/people`); null: the close owner."
          },
          "due_day": {
            "type": "integer",
            "maximum": 30.0,
            "minimum": 0.0,
            "title": "Due Day",
            "description": "The working day after the period end it is due on (0: the last day)."
          },
          "check_id": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_]{1,63}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Check Id",
            "description": "A close check that decides the task (the `id` of a check of `GET /v1/periods/{period_id}/close-checklist`): the task is done when the check passes or does not apply, and nobody marks it done by hand. Null for a task a person marks done."
          }
        },
        "type": "object",
        "required": [
          "title",
          "due_day"
        ],
        "title": "TaskInput",
        "examples": [
          {
            "due_day": 2,
            "owner_user_id": "1a2b3c4d-5e6f-4a7b-8c9d-0e1f2a3b4c5d",
            "title": "Reconcile the credit card account"
          },
          {
            "check_id": "ic_reconciled",
            "due_day": 3,
            "title": "Intercompany balances agreed"
          }
        ]
      },
      "TaskOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Task id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "What is to be done."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who does it; null: the close owner."
          },
          "due_day": {
            "type": "integer",
            "title": "Due Day",
            "description": "The working day after the period end it is due on."
          },
          "check_id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Check Id",
            "description": "The close check that decides it."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Part of the close."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "title",
          "owner",
          "due_day",
          "check_id",
          "active",
          "created_by",
          "created_at"
        ],
        "title": "TaskOut"
      },
      "TaskStatus": {
        "properties": {
          "task": {
            "$ref": "#/components/schemas/TaskOut",
            "description": "The task."
          },
          "due_date": {
            "type": "string",
            "format": "date",
            "title": "Due Date",
            "description": "The day it is due."
          },
          "status": {
            "type": "string",
            "enum": [
              "done",
              "n/a",
              "open",
              "overdue"
            ],
            "title": "Status",
            "description": "`done`, `open` (not done, not yet due), `overdue` (not done and its due date has passed) or `n/a` (nothing to do this period)."
          },
          "detail": {
            "type": "string",
            "title": "Detail",
            "description": "Why, in words."
          },
          "reason": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Reason"
              },
              {
                "type": "null"
              }
            ],
            "description": "`detail` by a stable code (`closeTracker.result`, or the deciding check's `periodClose.result`); null where the check gave no code."
          },
          "completion": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Completion"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who did it and with what evidence (a task a person marks done)."
          }
        },
        "type": "object",
        "required": [
          "task",
          "due_date",
          "status",
          "detail",
          "completion"
        ],
        "title": "TaskStatus"
      },
      "TaskUpdate": {
        "properties": {
          "title": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Title",
            "description": "New title."
          },
          "owner_user_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Owner User Id",
            "description": "New owner; null: the close owner."
          },
          "due_day": {
            "anyOf": [
              {
                "type": "integer",
                "maximum": 30.0,
                "minimum": 0.0
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Day",
            "description": "New working day."
          },
          "check_id": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_]{1,63}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Check Id",
            "description": "New check; null for none."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "false takes the task out of the close of the open periods for good (a task is never deleted, and a deactivated task is not reactivated: 409; create a new task)."
          }
        },
        "type": "object",
        "title": "TaskUpdate",
        "examples": [
          {
            "due_day": 3
          },
          {
            "active": false
          }
        ]
      },
      "TenantOut": {
        "properties": {
          "org_id": {
            "type": "string",
            "format": "uuid",
            "title": "Org Id",
            "description": "Id (uuid) of the organization."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The organization's name."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "suspended"
            ],
            "title": "Status",
            "description": "`active`, or `suspended`: the organization can read but not change anything until it is reactivated."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the organization was created (ISO 8601, UTC)."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it, as an actor object (`type`, `id`, `name`): a platform key (`platform:<prefix>`) or the command line."
          },
          "status_changed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Changed At",
            "description": "When it was last suspended or reactivated; null if never."
          },
          "status_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status Reason",
            "description": "Why it was last suspended or reactivated; null if never."
          },
          "kind": {
            "type": "string",
            "enum": [
              "customer",
              "demo"
            ],
            "title": "Kind",
            "description": "`customer`: its books are kept for the statutory period and never deleted. `demo`: made to be looked at. An operator deletes either in the portal (`POST /v1/platform/organizations/{org_id}/delete`, ADR-0042).",
            "default": "customer"
          },
          "copy_of": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Copy Of",
            "description": "For a test copy (always a `demo`), the organization it was made from (ADR-0039); null for every other organization."
          },
          "remove_requested_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Remove Requested At",
            "description": "When its deletion was asked for (`POST /v1/platform/organizations/{org_id}/delete`, or the removal of a test copy): nobody reaches it from then on, and an operator can undo it until `delete_after` (ADR-0042). Null otherwise."
          },
          "delete_after": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Delete After",
            "description": "When the owner's job may delete it for good: an hour after `remove_requested_at`. It runs every hour and at every deploy, so the organization is gone within the hour after this. Until then an operator can undo the deletion (`POST /v1/platform/organizations/{org_id}/undo-delete`). Null when no deletion was asked for."
          }
        },
        "type": "object",
        "required": [
          "org_id",
          "name",
          "status",
          "created_at",
          "created_by",
          "status_changed_at",
          "status_reason"
        ],
        "title": "TenantOut",
        "description": "An organization as the platform sees it: its lifecycle, never its books."
      },
      "TerminateInput": {
        "properties": {
          "termination_date": {
            "type": "string",
            "format": "date",
            "title": "Termination Date",
            "description": "The last day of the lease, ISO 8601: the last day of a lease month whose entries are posted."
          },
          "result_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Result Account",
            "description": "The account of the gain or loss. Default: the company's account for a gain or for a loss on disposal of assets."
          }
        },
        "type": "object",
        "required": [
          "termination_date"
        ],
        "title": "TerminateInput",
        "examples": [
          {
            "termination_date": "2027-07-31"
          }
        ]
      },
      "TheoreticalCapitalisation": {
        "properties": {
          "goodwill": {
            "type": "string",
            "title": "Goodwill",
            "description": "The goodwill at acquisition offset against equity."
          },
          "years": {
            "type": "integer",
            "title": "Years",
            "description": "The useful life it would be amortised over."
          },
          "amortisation_of_year": {
            "type": "string",
            "title": "Amortisation Of Year",
            "description": "The amortisation of the group year: the effect on the year's result."
          },
          "amortisation_earlier": {
            "type": "string",
            "title": "Amortisation Earlier",
            "description": "The amortisation of earlier years."
          },
          "translation_difference": {
            "type": "string",
            "title": "Translation Difference",
            "description": "The translation difference on it up to the group date (credit positive)."
          },
          "carrying_amount": {
            "type": "string",
            "title": "Carrying Amount",
            "description": "The theoretical carrying amount at the group date: the effect on equity."
          }
        },
        "type": "object",
        "required": [
          "goodwill",
          "years",
          "amortisation_of_year",
          "amortisation_earlier",
          "translation_difference",
          "carrying_amount"
        ],
        "title": "TheoreticalCapitalisation",
        "description": "What goodwill offset against equity would have given if capitalised and amortised over the\ngroup's useful life (Swiss GAAP FER 30/43: shown in the notes)."
      },
      "ToolCall": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The tool the agent called."
          },
          "input": {
            "additionalProperties": true,
            "type": "object",
            "title": "Input",
            "description": "The arguments it passed."
          },
          "ok": {
            "type": "boolean",
            "title": "Ok",
            "description": "False when the tool failed."
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "A short account of the result."
          }
        },
        "type": "object",
        "required": [
          "name",
          "input",
          "ok",
          "summary"
        ],
        "title": "ToolCall"
      },
      "Totals": {
        "properties": {
          "line_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line Total",
            "description": "BT-106"
          },
          "allowance_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Allowance Total",
            "description": "BT-107"
          },
          "charge_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Charge Total",
            "description": "BT-108"
          },
          "tax_exclusive": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Exclusive",
            "description": "BT-109"
          },
          "tax_total": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Total",
            "description": "BT-110"
          },
          "tax_total_accounting": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Total Accounting",
            "description": "BT-111"
          },
          "tax_inclusive": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Inclusive",
            "description": "BT-112"
          },
          "prepaid": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Prepaid",
            "description": "BT-113"
          },
          "rounding": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rounding",
            "description": "BT-114"
          },
          "payable": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payable",
            "description": "BT-115"
          },
          "third_party_payments": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Third Party Payments",
            "description": "Sum of BT-DEX-002 third party payments (XRechnung extension)"
          }
        },
        "type": "object",
        "title": "Totals",
        "description": "BG-22 document totals."
      },
      "TransferInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity."
          },
          "posting_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Date",
            "description": "The day; omitted: today."
          },
          "from_warehouse": {
            "type": "string",
            "title": "From Warehouse",
            "description": "Warehouse the goods leave (code or id)."
          },
          "to_warehouse": {
            "type": "string",
            "title": "To Warehouse",
            "description": "Warehouse they go to (code or id)."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 1000
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A note."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/TransferLine"
            },
            "type": "array",
            "maxItems": 500,
            "minItems": 1,
            "title": "Lines",
            "description": "The items."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "from_warehouse",
          "to_warehouse",
          "lines"
        ],
        "title": "TransferInput",
        "examples": [
          {
            "entity": "CH01",
            "from_warehouse": "ZRH",
            "lines": [
              {
                "item": "SCANNER",
                "quantity": "5"
              }
            ],
            "to_warehouse": "BSL"
          }
        ]
      },
      "TransferLine": {
        "properties": {
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code (or id) of the stock item."
          },
          "quantity": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*(?:\\d{0,14}|(?=[\\d.]{1,21}0*$)\\d{0,14}\\.\\d{0,6}0*$)"
              }
            ],
            "title": "Quantity",
            "description": "What moves. A quantity in the item's unit, up to six decimals, e.g. `12` or `2.5`."
          }
        },
        "type": "object",
        "required": [
          "item",
          "quantity"
        ],
        "title": "TransferLine"
      },
      "TranslatedTrialBalance": {
        "properties": {
          "run": {
            "type": "string",
            "format": "uuid",
            "title": "Run",
            "description": "Id of the run."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency."
          },
          "group_currency": {
            "type": "string",
            "title": "Group Currency",
            "description": "The reporting currency."
          },
          "translated": {
            "type": "boolean",
            "title": "Translated",
            "description": "False when the entity could not be translated: no lines."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/TranslatedTrialBalanceLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "The translated trial balance, by account code."
          },
          "local_debit": {
            "type": "string",
            "title": "Local Debit",
            "description": "Total debit in the functional currency."
          },
          "local_credit": {
            "type": "string",
            "title": "Local Credit",
            "description": "Total credit in the functional currency."
          },
          "group_debit": {
            "type": "string",
            "title": "Group Debit",
            "description": "Total debit in the reporting currency."
          },
          "group_credit": {
            "type": "string",
            "title": "Group Credit",
            "description": "Total credit in the reporting currency."
          },
          "balanced": {
            "type": "boolean",
            "title": "Balanced",
            "description": "True when the reporting-currency debits equal the credits."
          }
        },
        "type": "object",
        "required": [
          "run",
          "entity",
          "currency",
          "group_currency",
          "translated",
          "lines",
          "local_debit",
          "local_credit",
          "group_debit",
          "group_credit",
          "balanced"
        ],
        "title": "TranslatedTrialBalance"
      },
      "TranslatedTrialBalanceLine": {
        "properties": {
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Account code; null for the lines translation adds: the result of earlier years and the translation reserve."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name, or the name of the added line."
          },
          "report_line": {
            "type": "string",
            "title": "Report Line",
            "description": "The group report line it is aggregated on."
          },
          "local_debit": {
            "type": "string",
            "title": "Local Debit",
            "description": "Debit in the entity's functional currency (what was translated)."
          },
          "local_credit": {
            "type": "string",
            "title": "Local Credit",
            "description": "Credit in the entity's functional currency."
          },
          "group_debit": {
            "type": "string",
            "title": "Group Debit",
            "description": "Debit in the reporting currency."
          },
          "group_credit": {
            "type": "string",
            "title": "Group Credit",
            "description": "Credit in the reporting currency."
          },
          "rate_kind": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Kind",
            "description": "`closing`, `average`, `historical`, `mixed` (several rates) or `none`."
          },
          "rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate",
            "description": "The rate, or the effective rate of a line at several rates."
          }
        },
        "type": "object",
        "required": [
          "account",
          "name",
          "report_line",
          "local_debit",
          "local_credit",
          "group_debit",
          "group_credit",
          "rate_kind",
          "rate"
        ],
        "title": "TranslatedTrialBalanceLine"
      },
      "TrialBalance": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; all amounts are in it."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The report date (ISO 8601)."
          },
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/AccountBalance"
            },
            "type": "array",
            "title": "Accounts",
            "description": "One row per account with postings, ordered by code."
          },
          "total_debit": {
            "type": "string",
            "title": "Total Debit",
            "description": "Sum of the debit column."
          },
          "total_credit": {
            "type": "string",
            "title": "Total Credit",
            "description": "Sum of the credit column."
          },
          "balanced": {
            "type": "boolean",
            "title": "Balanced",
            "description": "True when total debit equals total credit."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "as_of",
          "accounts",
          "total_debit",
          "total_credit",
          "balanced"
        ],
        "title": "TrialBalance"
      },
      "UninvoicedLine": {
        "properties": {
          "note_id": {
            "type": "string",
            "format": "uuid",
            "title": "Note Id",
            "description": "The delivery note."
          },
          "number": {
            "type": "string",
            "title": "Number",
            "description": "Its number."
          },
          "delivery_date": {
            "type": "string",
            "format": "date",
            "title": "Delivery Date",
            "description": "The day the goods left."
          },
          "customer": {
            "type": "string",
            "title": "Customer",
            "description": "Customer code."
          },
          "customer_name": {
            "type": "string",
            "title": "Customer Name",
            "description": "Customer name."
          },
          "line_id": {
            "type": "string",
            "format": "uuid",
            "title": "Line Id",
            "description": "The delivery note line."
          },
          "line_no": {
            "type": "integer",
            "title": "Line No",
            "description": "Its position."
          },
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Stock item (product code)."
          },
          "item_name": {
            "type": "string",
            "title": "Item Name",
            "description": "Its name."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "Its unit."
          },
          "delivered": {
            "type": "string",
            "title": "Delivered",
            "description": "Quantity delivered less what came back."
          },
          "invoiced": {
            "type": "string",
            "title": "Invoiced",
            "description": "Quantity invoiced, net of credit notes."
          },
          "left": {
            "type": "string",
            "title": "Left",
            "description": "Delivered and not invoiced."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The functional currency of the value."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "What is left, at the cost it left with."
          }
        },
        "type": "object",
        "required": [
          "note_id",
          "number",
          "delivery_date",
          "customer",
          "customer_name",
          "line_id",
          "line_no",
          "item",
          "item_name",
          "unit",
          "delivered",
          "invoiced",
          "left",
          "currency",
          "value"
        ],
        "title": "UninvoicedLine"
      },
      "UnmatchRequest": {
        "properties": {
          "on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "On",
            "description": "Date of the reversal entry when undoing the match reverses a posted payment or posting, ISO 8601: not before it, in an open period. Default: today for a payment, the posting's own date for a posting."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the match is undone (required, at most 500 characters): on the reversal, in the approval request and in the audit trail."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "UnmatchRequest",
        "examples": [
          {
            "on": "2026-10-10",
            "reason": "Wrong invoice"
          }
        ]
      },
      "UnmatchResult": {
        "properties": {
          "line": {
            "$ref": "#/components/schemas/BankLineOut",
            "description": "The line after the request."
          },
          "outcome": {
            "type": "string",
            "enum": [
              "pending_approval",
              "reversed",
              "unlinked",
              "withdrawn"
            ],
            "title": "Outcome",
            "description": "`unlinked`: the line was linked to a payment booked before (a released payment), which stands; `withdrawn`: the payment or posting the match made still waited for approval and is rejected; `reversed`: the payment or posting the match made is reversed; `pending_approval`: its reversal waits for a second person (`approval_id`) and the line stays matched until it is approved. In every other case the line is unmatched again."
          },
          "reversal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversal Entry Id",
            "description": "The reversal entry, when one was made (posted or waiting)."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request the reversal waits for, if it does."
          }
        },
        "type": "object",
        "required": [
          "line",
          "outcome"
        ],
        "title": "UnmatchResult"
      },
      "UnregisteredStateRow": {
        "properties": {
          "state": {
            "type": "string",
            "title": "State",
            "description": "A state the company sold into without a registration."
          },
          "state_name": {
            "type": "string",
            "title": "State Name",
            "description": "Its name."
          },
          "sales": {
            "type": "string",
            "title": "Sales",
            "description": "Its sales there in the period, net of credit notes."
          },
          "documents": {
            "type": "integer",
            "title": "Documents",
            "description": "How many invoices and credit notes."
          }
        },
        "type": "object",
        "required": [
          "state",
          "state_name",
          "sales",
          "documents"
        ],
        "title": "UnregisteredStateRow"
      },
      "UnusualEntry": {
        "properties": {
          "id": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Id",
            "description": "Id (uuid) of the entry, as text."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "The entry number."
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "The posting date (ISO 8601)."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the entry is for."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "`manual` or the subledger that created it."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Total debits in functional currency."
          },
          "created_by": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created By",
            "description": "Name of the actor that created the entry."
          },
          "created_by_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Created By Type",
            "description": "`human`, `agent` or `system`."
          },
          "reverses": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reverses",
            "description": "Id of the entry this one reverses."
          },
          "flags": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Flags",
            "description": "manual entry, created by an agent, round amount, large amount, weekend date, reversal."
          }
        },
        "type": "object",
        "required": [
          "number",
          "date",
          "description",
          "source",
          "amount",
          "created_by",
          "created_by_type",
          "reverses",
          "flags"
        ],
        "title": "UnusualEntry"
      },
      "UptimeCheckOut": {
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The check's name, for example `data-vNext erp`."
          },
          "url": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Url",
            "description": "What it fetches."
          },
          "status": {
            "type": "string",
            "enum": [
              "down",
              "no_data",
              "up"
            ],
            "title": "Status",
            "description": "`up` when at least 80% of the probes of the last 15 minutes passed (one region failing is a blip, as in the alert); `down` otherwise; `no_data`."
          },
          "success_ratio_15m": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Success Ratio 15M",
            "description": "Passed probes in the last 15 minutes."
          },
          "success_ratio_24h": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "null"
              }
            ],
            "title": "Success Ratio 24H",
            "description": "Passed probes in the last 24 hours."
          }
        },
        "type": "object",
        "required": [
          "name",
          "url",
          "status",
          "success_ratio_15m",
          "success_ratio_24h"
        ],
        "title": "UptimeCheckOut",
        "description": "A synthetic probe from outside Google's network, every five minutes."
      },
      "UserOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id (uuid) of the user."
          },
          "email": {
            "type": "string",
            "title": "Email",
            "description": "The sign-in address, lower case."
          },
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Display name; null until set."
          },
          "scopes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Scopes",
            "description": "The scopes the user holds: some of `read`, `draft`, `post`, `approve`, `admin`, `audit`."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`invited` (never signed in), `active` or `disabled`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When the user was invited (ISO 8601, UTC)."
          },
          "last_login_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Last Login At",
            "description": "The last sign-in; null if never."
          },
          "locale": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Locale",
            "description": "The user's UI language (`en`, `de-CH`, `fr-CH`, `it-CH`, `sv-SE`); null follows the browser."
          },
          "access_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Until",
            "description": "When the person's access ends (ISO 8601, UTC): from then on they cannot sign in and their sessions stop. Null for no end. An external auditor always has one."
          }
        },
        "type": "object",
        "required": [
          "id",
          "email",
          "name",
          "scopes",
          "status",
          "created_at",
          "last_login_at"
        ],
        "title": "UserOut"
      },
      "UserUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New display name; omit to keep it."
          },
          "role": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "accountant",
                  "admin",
                  "auditor",
                  "controller",
                  "viewer"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "A preset replacing the user's scopes: `viewer` (read), `auditor` (read, audit), `accountant` (read, draft, post), `controller` (plus approve) or `admin` (all). Not together with `scopes`."
          },
          "scopes": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Scopes",
            "description": "Explicit scopes replacing the user's: `read`, `draft`, `post`, `approve`, `admin`, `audit`. Not together with `role`."
          },
          "access_until": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Access Until",
            "description": "A new end of the person's access (in the future, at most two years ahead), or null to remove the end (not for an external auditor, whose access always ends). Omit to keep it. To end access now, disable the person. Nobody sets their own."
          },
          "status": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "active",
                  "disabled"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "`active` or `disabled`; disabling ends the user's sessions, blocks sign-in and revokes the API keys they issued (and the keys those issued). Omit to keep it."
          },
          "approver": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/ApproverDeclaration"
              },
              {
                "type": "null"
              }
            ],
            "description": "Who the person is, declared by the administrator: required when the new access lets the person approve and the old did not (422 `approver_declaration_missing`; 409 `approver_same_person`). Recorded in the audit trail and the approver register."
          }
        },
        "type": "object",
        "title": "UserUpdate",
        "examples": [
          {
            "role": "controller"
          },
          {
            "access_until": "2027-03-31T23:59:59Z"
          }
        ]
      },
      "ValidationError": {
        "properties": {
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "type": "array",
            "title": "Location"
          },
          "msg": {
            "type": "string",
            "title": "Message"
          },
          "type": {
            "type": "string",
            "title": "Error Type"
          },
          "input": {
            "title": "Input"
          },
          "ctx": {
            "type": "object",
            "title": "Context"
          }
        },
        "type": "object",
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError"
      },
      "ValuationLine": {
        "properties": {
          "product_id": {
            "type": "string",
            "format": "uuid",
            "title": "Product Id",
            "description": "Product id."
          },
          "item": {
            "type": "string",
            "title": "Item",
            "description": "Product code."
          },
          "item_name": {
            "type": "string",
            "title": "Item Name",
            "description": "Product name."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "Unit."
          },
          "inventory_account": {
            "type": "string",
            "title": "Inventory Account",
            "description": "Code of its inventory account."
          },
          "quantity": {
            "type": "string",
            "title": "Quantity",
            "description": "Quantity on the day (all warehouses, or the one asked)."
          },
          "value": {
            "type": "string",
            "title": "Value",
            "description": "Value on the day (company-wide; per item, not warehouse)."
          },
          "average_cost": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Average Cost",
            "description": "Value / quantity; null without quantity."
          }
        },
        "type": "object",
        "required": [
          "product_id",
          "item",
          "item_name",
          "unit",
          "inventory_account",
          "quantity",
          "value",
          "average_cost"
        ],
        "title": "ValuationLine"
      },
      "ValuationOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "as_of": {
            "type": "string",
            "format": "date",
            "title": "As Of",
            "description": "The day, end of day."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Functional currency."
          },
          "warehouse": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Warehouse",
            "description": "The warehouse asked for; quantities only."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/ValuationLine"
            },
            "type": "array",
            "title": "Lines",
            "description": "Every item with a quantity or a value."
          },
          "total": {
            "type": "string",
            "title": "Total",
            "description": "Total value of the stock."
          },
          "ledger": {
            "type": "string",
            "title": "Ledger",
            "description": "Balance of the inventory accounts on the day from posted entries."
          },
          "difference": {
            "type": "string",
            "title": "Difference",
            "description": "Total less ledger: zero, since only stock postings book the inventory accounts."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "as_of",
          "currency",
          "warehouse",
          "lines",
          "total",
          "ledger",
          "difference"
        ],
        "title": "ValuationOut"
      },
      "ValueInput": {
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,30}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Letters, digits, `.`, `_` and `-`, at most 31 characters; never changes. Omitted: made from the name (`Sales Zurich` is `SALES-ZURICH`)."
          },
          "name": {
            "type": "string",
            "maxLength": 120,
            "minLength": 1,
            "title": "Name",
            "description": "The name shown on screens and reports."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code of the only company that may use it; omitted: every one."
          },
          "valid_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid From",
            "description": "First day lines may name it."
          },
          "valid_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid To",
            "description": "Last day lines may name it."
          }
        },
        "type": "object",
        "required": [
          "name"
        ],
        "title": "ValueInput",
        "examples": [
          {
            "code": "CC-100",
            "name": "Sales Zurich"
          }
        ]
      },
      "ValueOut": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The value's code, as lines name it, e.g. `CC-100`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The value's name, e.g. `Sales Zurich`."
          },
          "entity": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entity",
            "description": "Code of the only company that may use it; null: every company."
          },
          "valid_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid From",
            "description": "First day lines may name it; null: no limit."
          },
          "valid_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid To",
            "description": "Last day lines may name it; null: no limit."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether new lines may name it."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "entity",
          "valid_from",
          "valid_to",
          "active"
        ],
        "title": "ValueOut"
      },
      "ValueUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 120,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "A new name; omitted: unchanged."
          },
          "valid_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid From",
            "description": "A new first day; omitted: unchanged."
          },
          "valid_to": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Valid To",
            "description": "A new last day; omitted: unchanged."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "`false` stops new lines naming it; lines posted with it stay as they are."
          }
        },
        "type": "object",
        "title": "ValueUpdate",
        "examples": [
          {
            "valid_to": "2026-12-31"
          },
          {
            "active": false
          }
        ]
      },
      "VarianceApproval": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "title": "Reason",
            "description": "Why the variance is fine; required (refused with `variance_reason_missing` when empty).",
            "default": ""
          }
        },
        "type": "object",
        "title": "VarianceApproval",
        "examples": [
          {
            "reason": "Price increase agreed by phone with the supplier"
          }
        ]
      },
      "VatAccountReconciliation": {
        "properties": {
          "account": {
            "type": "string",
            "title": "Account",
            "description": "VAT account code."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Account name."
          },
          "role": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Role",
            "description": "Account role: `vat_output`, `vat_reverse_charge` or `vat_input`."
          },
          "ledger": {
            "type": "string",
            "title": "Ledger",
            "description": "Posted movement in the period, credit minus debit, without settlement entries."
          },
          "reported": {
            "type": "string",
            "title": "Reported",
            "description": "What the return takes of it, as on the return: foreign-currency VAT at the official VAT exchange rate. `ledger` = `reported` - `tax_fx_difference` + `other_period` + `unmapped` + `untagged`."
          },
          "tax_fx_difference": {
            "type": "string",
            "title": "Tax Fx Difference",
            "description": "What the official VAT exchange rates add to the VAT booked on this account (the return at the official rate less the ledger at the booking rate). The differences of the output and input tax accounts can cancel in the amount payable (acquisition tax) while each box differs from its account.",
            "default": "0.00"
          },
          "other_period": {
            "type": "string",
            "title": "Other Period",
            "description": "VAT booked in this period whose tax point is in another period, less VAT of this period's tax points booked in another period: the date of supply moved it (goods delivered in September and invoiced in October are on the September return, in the October ledger), or the cash basis (an invoice booked in September is on the return of the period it is paid in, pro rata). Explained, not part of `unexplained`.",
            "default": "0.00"
          },
          "unmapped": {
            "type": "string",
            "title": "Unmapped",
            "description": "Tax-tagged amount that no box takes."
          },
          "untagged": {
            "type": "string",
            "title": "Untagged",
            "description": "Movement without a tax code (for example manual postings)."
          }
        },
        "type": "object",
        "required": [
          "account",
          "name",
          "role",
          "ledger",
          "reported",
          "unmapped",
          "untagged"
        ],
        "title": "VatAccountReconciliation"
      },
      "VatActivity": {
        "properties": {
          "activity_id": {
            "type": "string",
            "title": "Activity Id",
            "description": "The ESTV's five-character activity code."
          },
          "series": {
            "type": "string",
            "title": "Series",
            "description": "Net tax rate series."
          },
          "activity": {
            "type": "string",
            "title": "Activity",
            "description": "Name of the activity."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "Net tax rate in percent."
          },
          "turnover": {
            "type": "string",
            "title": "Turnover",
            "description": "Gross turnover of the activity."
          },
          "tax": {
            "type": "string",
            "title": "Tax",
            "description": "Tax at the net tax rate."
          }
        },
        "type": "object",
        "required": [
          "activity_id",
          "series",
          "activity",
          "rate",
          "turnover",
          "tax"
        ],
        "title": "VatActivity",
        "description": "Net tax rate method: turnover (gross) and tax per approved activity."
      },
      "VatAdjustment-Input": {
        "properties": {
          "box": {
            "type": "string",
            "title": "Box",
            "description": "Id of the box to adjust, as in the return's `boxes[].id` (a Ziffer such as `410` or a Kennzahl). Only boxes that the ledger neither fills nor computes can be adjusted (`adjustable` is true); others are refused (422)."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Amount",
            "description": "Amount to add to the box, as a decimal string in the entity's functional currency, e.g. `\"120.00\"`. Negative reduces the box."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Offset account in the settlement; required for boxes that change the amount payable (e.g. import VAT paid to customs)."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Free text explaining the adjustment. Optional."
          },
          "automatic": {
            "type": "boolean",
            "title": "Automatic",
            "description": "Filled in by the return itself (CA: the Quick Method 1% credit, instalments paid; ES: amounts carried forward, the Modelo 390 from the 303s); replaced on every recompute, so only adjustments entered by hand are kept.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "box",
          "amount"
        ],
        "title": "VatAdjustment",
        "description": "An amount entered by hand for a box the ledger does not fill (e.g. import VAT).",
        "examples": [
          {
            "account": "1020",
            "amount": "120.00",
            "box": "410",
            "note": "Import VAT paid to customs"
          }
        ]
      },
      "VatAdjustment-Output": {
        "properties": {
          "box": {
            "type": "string",
            "title": "Box",
            "description": "Id of the box to adjust, as in the return's `boxes[].id` (a Ziffer such as `410` or a Kennzahl). Only boxes that the ledger neither fills nor computes can be adjusted (`adjustable` is true); others are refused (422)."
          },
          "amount": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Amount",
            "description": "Amount to add to the box, as a decimal string in the entity's functional currency, e.g. `\"120.00\"`. Negative reduces the box."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "Offset account in the settlement; required for boxes that change the amount payable (e.g. import VAT paid to customs)."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Free text explaining the adjustment. Optional."
          },
          "automatic": {
            "type": "boolean",
            "title": "Automatic",
            "description": "Filled in by the return itself (CA: the Quick Method 1% credit, instalments paid; ES: amounts carried forward, the Modelo 390 from the 303s); replaced on every recompute, so only adjustments entered by hand are kept.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "box",
          "amount"
        ],
        "title": "VatAdjustment",
        "description": "An amount entered by hand for a box the ledger does not fill (e.g. import VAT).",
        "examples": [
          {
            "account": "1020",
            "amount": "120.00",
            "box": "410",
            "note": "Import VAT paid to customs"
          }
        ]
      },
      "VatBox": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Box id, as used in `adjustments[].box` and `.../boxes/{box}/lines`, e.g. `303` or `kz81`."
          },
          "code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "The number printed on the form (Ziffer, Kennzahl); null if unnumbered."
          },
          "line": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Line",
            "description": "Line number on the form, if any."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "The official wording, abridged."
          },
          "section": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Section",
            "description": "Section of the form the box is in."
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "`base` (turnover or taxable amount), `tax` or `amount`."
          },
          "rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate",
            "description": "The rate printed next to the box, in percent."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The box's amount in the return's currency, as a decimal string."
          },
          "tax": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax",
            "description": "For boxes that compute tax, the tax on the amount; else null."
          },
          "computed": {
            "type": "boolean",
            "title": "Computed",
            "description": "True when the form derives the box from other boxes."
          },
          "lines": {
            "type": "integer",
            "title": "Lines",
            "description": "Number of journal lines that fill the box (drill down with `.../boxes/{box}/lines`)."
          },
          "adjustable": {
            "type": "boolean",
            "title": "Adjustable",
            "description": "True when the box can take a hand-entered adjustment."
          },
          "adjusted": {
            "type": "boolean",
            "title": "Adjusted",
            "description": "True when an adjustment is part of the amount.",
            "default": false
          },
          "filled": {
            "type": "boolean",
            "title": "Filled",
            "description": "True when the amount comes from the company's earlier returns rather than from the ledger (Italy: the previous period's credit or carried debt, the interest on quarterly payments, the year's periodic VAT on the annual return).",
            "default": false
          },
          "xml": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Xml",
            "description": "Element of the eCH-0217 file the box is written to, if any."
          },
          "by_rate": {
            "items": {
              "$ref": "#/components/schemas/VatRatePart"
            },
            "type": "array",
            "title": "By Rate",
            "description": "Boxes that compute tax: amount and tax per rate."
          }
        },
        "type": "object",
        "required": [
          "id",
          "code",
          "line",
          "label",
          "section",
          "unit",
          "rate",
          "amount",
          "tax",
          "computed",
          "lines",
          "adjustable"
        ],
        "title": "VatBox"
      },
      "VatBoxLine": {
        "properties": {
          "journal_line_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Line Id",
            "description": "Id of the journal line that fills the box."
          },
          "entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Entry Id",
            "description": "Id of its journal entry (`GET /v1/journal-entries/{id}`)."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Number of the journal entry."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "Posting date of the entry (ISO 8601 date)."
          },
          "account": {
            "type": "string",
            "title": "Account",
            "description": "Account code of the line."
          },
          "account_name": {
            "type": "string",
            "title": "Account Name",
            "description": "Account name."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "The line's description."
          },
          "document": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document",
            "description": "For receivable and payable postings, the document number."
          },
          "counterparty": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Counterparty",
            "description": "Name of the customer or vendor on the line."
          },
          "row_key": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Row Key",
            "description": "Recapitulative statement: the customer VAT number (country code and id) the line belongs to."
          },
          "rule": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rule",
            "description": "Id of the form rule that routed the line into the box."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The line's contribution to the box in the return's currency, as a decimal string."
          }
        },
        "type": "object",
        "required": [
          "journal_line_id",
          "entry_id",
          "entry_number",
          "entry_date",
          "account",
          "account_name",
          "description",
          "document",
          "counterparty",
          "row_key",
          "rule",
          "amount"
        ],
        "title": "VatBoxLine"
      },
      "VatBreakdown": {
        "properties": {
          "taxable_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Taxable Amount",
            "description": "BT-116"
          },
          "tax_amount": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Amount",
            "description": "BT-117"
          },
          "category": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Category",
            "description": "BT-118"
          },
          "rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate",
            "description": "BT-119"
          },
          "exemption_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption Reason",
            "description": "BT-120"
          },
          "exemption_reason_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Exemption Reason Code",
            "description": "BT-121"
          }
        },
        "type": "object",
        "title": "VatBreakdown",
        "description": "BG-23."
      },
      "VatCorrectionInput": {
        "properties": {
          "write_off_id": {
            "type": "string",
            "format": "uuid",
            "title": "Write Off Id",
            "description": "The posted write-off whose VAT was kept, now that the loss is final."
          },
          "correction_date": {
            "type": "string",
            "format": "date",
            "title": "Correction Date",
            "description": "The day the loss became final (ISO 8601): on or after the write-off, not after today, in an open period."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 500
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "Why the loss is final now."
          }
        },
        "type": "object",
        "required": [
          "write_off_id",
          "correction_date"
        ],
        "title": "VatCorrectionInput",
        "examples": [
          {
            "correction_date": "2026-12-15",
            "note": "Bankruptcy closed; certificate of loss received.",
            "write_off_id": "0f6b6a3e-5d7c-4b8e-9a51-2f4c1d0e7a90"
          }
        ]
      },
      "VatFinalizeInput": {
        "properties": {
          "posting_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Posting Date",
            "description": "Date of the settlement entry; default the period's last day, or the first open day after it."
          },
          "explanation": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Explanation",
            "description": "Required when the VAT accounts hold amounts the return does not explain."
          }
        },
        "type": "object",
        "title": "VatFinalizeInput",
        "examples": [
          {
            "explanation": "The difference is a manual VAT correction booked on 2026-09-12.",
            "posting_date": "2026-09-30"
          }
        ]
      },
      "VatFinalizeOut": {
        "properties": {
          "vat_return": {
            "$ref": "#/components/schemas/VatReturnOut",
            "description": "The return after the call: `final`, or `pending_approval` when the settlement entry needs a second person."
          },
          "settlement": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/SubmitResult"
              },
              {
                "type": "null"
              }
            ],
            "description": "The settlement entry's submission: its id, status, number, the policy decision (`allow`, `require_approval`, `deny`) and the approval id when one was requested. Null when nothing needed settling."
          }
        },
        "type": "object",
        "required": [
          "vat_return",
          "settlement"
        ],
        "title": "VatFinalizeOut"
      },
      "VatForm": {
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Form id, e.g. `ch.estv.mwst.effective` or `de.bmf.ustva.2026`."
          },
          "jurisdiction": {
            "type": "string",
            "title": "Jurisdiction",
            "description": "Country the form is filed in, e.g. `IT`.",
            "default": ""
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Official name of the form."
          },
          "kind": {
            "type": "string",
            "enum": [
              "annual_summary",
              "oss_return",
              "pst_return_bc",
              "pst_return_sk",
              "qst_return",
              "recapitulative_statement",
              "rst_return_mb",
              "vat_return"
            ],
            "title": "Kind",
            "description": "`vat_return`, `recapitulative_statement` (ZM, Modelo 349), `qst_return` (Quebec), `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary` (Modelo 390, Dichiarazione IVA) or `oss_return` (EU One-Stop Shop, union scheme)."
          },
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Filing method the form is for, or null."
          },
          "version": {
            "type": "string",
            "title": "Version",
            "description": "Edition of the form or file format it follows."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency the form is filed in; the entity must book in it."
          },
          "base_precision": {
            "type": "integer",
            "title": "Base Precision",
            "description": "Decimals of base amounts: 0 means whole units."
          },
          "tax_precision": {
            "type": "integer",
            "title": "Tax Precision",
            "description": "Decimals of tax amounts and totals: 0 means whole units (FR, IT).",
            "default": 2
          },
          "notes": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Notes",
            "description": "How the form computes and rounds."
          },
          "limitations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Limitations",
            "description": "What the form does not derive from the ledger (enter it as adjustments)."
          },
          "sources": {
            "items": {
              "additionalProperties": true,
              "type": "object"
            },
            "type": "array",
            "title": "Sources",
            "description": "Legal and technical sources of the form."
          }
        },
        "type": "object",
        "required": [
          "id",
          "name",
          "kind",
          "method",
          "version",
          "currency",
          "base_precision",
          "notes",
          "limitations",
          "sources"
        ],
        "title": "VatForm"
      },
      "VatIssue": {
        "properties": {
          "severity": {
            "type": "string",
            "enum": [
              "error",
              "info",
              "warning"
            ],
            "title": "Severity",
            "description": "`error` (blocks finalising), `warning` (review it) or `info`."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Stable code (`erp.contracts.words.VAT_ISSUES` lists them all), e.g. `unmapped_line`, `unexplained_difference`, `computation_difference` (with `computation_difference_fx` when official VAT exchange rates add to it), `tax_fx_not_published`, `missing_uid`, `missing_account`, `missing_settlement_account`, `period_differs_from_settings`, `earlier_period_unfiled` (an earlier period has no final return yet: filing this one is allowed), `annual_differs` (vs. the final returns)."
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "What was found, in English."
          },
          "details": {
            "additionalProperties": {
              "type": "string"
            },
            "type": "object",
            "title": "Details",
            "description": "The values the message names, for the screens to word it, e.g. `{\"periods\": \"2026-Q1, 2026-Q2\"}` for `earlier_period_unfiled`."
          }
        },
        "type": "object",
        "required": [
          "severity",
          "code",
          "message"
        ],
        "title": "VatIssue"
      },
      "VatLine-Input": {
        "properties": {
          "rate": {
            "anyOf": [
              {
                "type": "number",
                "maximum": 100.0,
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Rate",
            "description": "The VAT rate printed, in percent (`8.1`)."
          },
          "net": {
            "anyOf": [
              {
                "type": "number"
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Net",
            "description": "The amount before VAT at this rate."
          },
          "vat": {
            "anyOf": [
              {
                "type": "number",
                "minimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              }
            ],
            "title": "Vat",
            "description": "The VAT printed at this rate."
          }
        },
        "type": "object",
        "required": [
          "rate",
          "net",
          "vat"
        ],
        "title": "VatLine"
      },
      "VatLine-Output": {
        "properties": {
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "The VAT rate printed, in percent (`8.1`)."
          },
          "net": {
            "type": "string",
            "title": "Net",
            "description": "The amount before VAT at this rate."
          },
          "vat": {
            "type": "string",
            "title": "Vat",
            "description": "The VAT printed at this rate."
          }
        },
        "type": "object",
        "required": [
          "rate",
          "net",
          "vat"
        ],
        "title": "VatLine"
      },
      "VatNetTaxRate": {
        "properties": {
          "series": {
            "type": "string",
            "pattern": "^[a-z0-9_.-]+$",
            "title": "Series",
            "description": "data-vNext net tax rate series approved by the ESTV, e.g. 'ch.vat.net_rate.software_entwicklung'."
          },
          "activity_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9]{5}$",
            "title": "Activity Id",
            "description": "The ESTV's five-character activity code (eCH-0217 activityID)."
          },
          "accounts": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Accounts",
            "description": "Revenue accounts declared under this activity; empty: all other accounts."
          }
        },
        "type": "object",
        "required": [
          "series",
          "activity_id"
        ],
        "title": "VatNetTaxRate",
        "examples": [
          {
            "accounts": [
              "3400"
            ],
            "activity_id": "A1234",
            "series": "ch.vat.net_rate.treuhandbuero"
          }
        ]
      },
      "VatOssCorrection": {
        "properties": {
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The quarter corrected (`YYYY-Qn`)."
          },
          "member_state": {
            "type": "string",
            "title": "Member State",
            "description": "Member state of consumption (ISO 3166-1 alpha-2)."
          },
          "vat": {
            "type": "string",
            "title": "Vat",
            "description": "Change of the VAT of that quarter in euros (negative: less)."
          }
        },
        "type": "object",
        "required": [
          "period",
          "member_state",
          "vat"
        ],
        "title": "VatOssCorrection",
        "description": "A correction in a One-Stop Shop return of the VAT declared for an earlier quarter."
      },
      "VatOssRow": {
        "properties": {
          "member_state": {
            "type": "string",
            "title": "Member State",
            "description": "Member state of consumption (ISO 3166-1 alpha-2)."
          },
          "supply": {
            "type": "string",
            "enum": [
              "goods",
              "services"
            ],
            "title": "Supply",
            "description": "`goods` or `services`."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "VAT rate of that member state in percent."
          },
          "rate_type": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate Type",
            "description": "`standard`, `reduced`, ... or null."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "Taxable amount in euros."
          },
          "vat": {
            "type": "string",
            "title": "Vat",
            "description": "VAT due in that member state in euros."
          }
        },
        "type": "object",
        "required": [
          "member_state",
          "supply",
          "rate",
          "rate_type",
          "base",
          "vat"
        ],
        "title": "VatOssRow",
        "description": "A row of the One-Stop Shop return: one member state of consumption, kind of supply and\nVAT rate."
      },
      "VatPaymentCandidate": {
        "properties": {
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "Id of the posted entry."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Its number."
          },
          "entry_date": {
            "type": "string",
            "format": "date",
            "title": "Entry Date",
            "description": "Its date (ISO 8601 date)."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "Its description."
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Its source, such as `bank` or `manual`."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What it puts on the settlement account against the settlement, as a positive decimal string."
          }
        },
        "type": "object",
        "required": [
          "journal_entry_id",
          "entry_number",
          "entry_date",
          "description",
          "source",
          "amount"
        ],
        "title": "VatPaymentCandidate"
      },
      "VatPaymentInput": {
        "properties": {
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "The posted entry that paid the VAT (or received the refund): of the return's company, dated on or after the settlement, with a line on the settlement account on the side opposite the settlement (`GET .../payment-candidates`)."
          }
        },
        "type": "object",
        "required": [
          "journal_entry_id"
        ],
        "title": "VatPaymentInput",
        "examples": [
          {
            "journal_entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
          }
        ]
      },
      "VatPaymentOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the link (the `{payment_id}` to unlink it)."
          },
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "Id of the posted entry that paid."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Number of that entry."
          },
          "paid_on": {
            "type": "string",
            "format": "date",
            "title": "Paid On",
            "description": "The entry's date: the day it paid (ISO 8601 date)."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What the entry put on the settlement account against the settlement, as a positive decimal string: VAT paid, or for a refund the refund received."
          },
          "linked_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Linked By",
            "description": "Who linked it (type and id)."
          },
          "linked_at": {
            "type": "string",
            "format": "date-time",
            "title": "Linked At",
            "description": "When it was linked (ISO 8601 timestamp, UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "journal_entry_id",
          "entry_number",
          "paid_on",
          "amount",
          "linked_by",
          "linked_at"
        ],
        "title": "VatPaymentOut"
      },
      "VatPeriod": {
        "properties": {
          "filing_status": {
            "type": "string",
            "enum": [
              "not_submitted",
              "paid",
              "submitted"
            ],
            "title": "Filing Status",
            "description": "`not_submitted` (not final yet, or final but not recorded as submitted), `submitted` (a person recorded the submission; a return with nothing to pay or refund stays here) or `paid` (submitted, and the linked payments cover the settled amount)."
          },
          "submitted_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted On",
            "description": "The day the return was submitted to the tax administration, as a person recorded it (ISO 8601 date); null when not submitted."
          },
          "submission_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submission Reference",
            "description": "The tax administration's reference or confirmation number, or null."
          },
          "submitted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted By",
            "description": "Who recorded the submission (type and id); null when not submitted."
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At",
            "description": "When the submission was recorded (ISO 8601 timestamp, UTC), or null."
          },
          "settled_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settled Amount",
            "description": "What the posted settlement put on the settlement account: positive is VAT to pay, negative a refund to receive (a correction: only its difference). Null when nothing was settled (not final yet, nothing to pay, a recapitulative statement)."
          },
          "paid_amount": {
            "type": "string",
            "title": "Paid Amount",
            "description": "What the linked payments cover, signed like `settled_amount`."
          },
          "payment_difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Difference",
            "description": "`settled_amount` minus `paid_amount`: what is still to pay (or receive); negative when more was paid. Null when nothing was settled."
          },
          "payments": {
            "items": {
              "$ref": "#/components/schemas/VatPaymentOut"
            },
            "type": "array",
            "title": "Payments",
            "description": "The posted entries linked as paying the return, oldest first."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "Period label: `2026-Q3`, `2026-08`, `2026-H2` or `2026`."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the period (ISO 8601 date)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the period (ISO 8601 date)."
          },
          "kind": {
            "type": "string",
            "enum": [
              "annual_summary",
              "oss_return",
              "pst_return_bc",
              "pst_return_sk",
              "qst_return",
              "recapitulative_statement",
              "rst_return_mb",
              "vat_return"
            ],
            "title": "Kind",
            "description": "`vat_return`, `recapitulative_statement` (ZM, Modelo 349), `qst_return` (Quebec), `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary` (Modelo 390, Dichiarazione IVA) or `oss_return` (EU One-Stop Shop, union scheme)."
          },
          "return_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Return Id",
            "description": "Id of the period's live return, or null when there is none."
          },
          "reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reference",
            "description": "Reference of that return, or null."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "The return's status (`draft`, `pending_approval`, `final`, `amending`) or `open` when the period has no live return."
          },
          "payable": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payable",
            "description": "The return's amount payable as a decimal string, or null."
          },
          "due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Due Date",
            "description": "When the return is due to be filed and paid (ISO 8601 date), by the country's rule (CH: 60 days after the period; DE: the 10th of the next month, a month later with the permanent extension, a recapitulative statement on the 25th day, moved to the Monday when it falls on a weekend; GB: one month and seven days, two months after the year under the Annual Accounting Scheme); null when no rule is known for the country or period."
          },
          "payment_due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Due Date",
            "description": "When the period's VAT is due to be paid (ISO 8601 date): the `due_date`, except in Italy, where it is paid before the return is filed (the 16th of the next month; quarterly 16 May, 20 August, 16 November and, with the annual balance, 16 March); null when nothing is paid on the return (an annual return) or no rule is known."
          },
          "due_status": {
            "type": "string",
            "enum": [
              "due_soon",
              "filed",
              "overdue",
              "unknown",
              "upcoming"
            ],
            "title": "Due Status",
            "description": "`filed` (a return of the period was recorded as submitted to the tax administration; final alone is not filed), `upcoming`, `due_soon` (due within 14 days), `overdue` (past the due date and not filed) or `unknown` (no due date known).",
            "default": "unknown"
          },
          "payment_overdue": {
            "type": "boolean",
            "title": "Payment Overdue",
            "description": "`true` when the due date has passed and the live return's VAT to pay is not covered by linked payments (shown as a warning; `due_status` follows the filing only).",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "filing_status",
          "submitted_on",
          "submission_reference",
          "submitted_by",
          "submitted_at",
          "settled_amount",
          "paid_amount",
          "payment_difference",
          "payments",
          "period",
          "start",
          "end",
          "kind",
          "return_id",
          "reference",
          "status",
          "payable"
        ],
        "title": "VatPeriod"
      },
      "VatRateChoice": {
        "properties": {
          "series": {
            "type": "string",
            "title": "Series",
            "description": "The rate's series in data-vNext, e.g. `fr.vat.reduced`."
          },
          "rate": {
            "type": "string",
            "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$",
            "title": "Rate",
            "description": "Percent, e.g. `5.5`; 0 for an exempt supply."
          },
          "categories": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Categories",
            "description": "What the rate applies to, in English words, e.g. `books`. A line names one of them as its `tax_category` to choose this rate."
          },
          "description": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Description",
            "description": "The legal basis or a remark; null for none."
          }
        },
        "type": "object",
        "required": [
          "series",
          "rate",
          "categories",
          "description"
        ],
        "title": "VatRateChoice"
      },
      "VatRatePart": {
        "properties": {
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "Tax rate in percent."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Turnover at that rate."
          },
          "tax": {
            "type": "string",
            "title": "Tax",
            "description": "Tax on that turnover."
          }
        },
        "type": "object",
        "required": [
          "rate",
          "amount",
          "tax"
        ],
        "title": "VatRatePart"
      },
      "VatRateTypeChoice": {
        "properties": {
          "rate_type": {
            "type": "string",
            "enum": [
              "exempt",
              "parking",
              "reduced",
              "special",
              "standard",
              "super_reduced",
              "zero"
            ],
            "title": "Rate Type",
            "description": "The rate type a line sends as `rate_type`."
          },
          "rates": {
            "items": {
              "$ref": "#/components/schemas/VatRateChoice"
            },
            "type": "array",
            "title": "Rates",
            "description": "The rates of the type in force, at least one."
          },
          "category_needed": {
            "type": "boolean",
            "title": "Category Needed",
            "description": "True when the type has several rates (France: reduced 5.5 % and 10 %) or several kinds of exemption (Switzerland): a line of this type must name its `tax_category`, else the document is refused with `tax_category_needed`."
          }
        },
        "type": "object",
        "required": [
          "rate_type",
          "rates",
          "category_needed"
        ],
        "title": "VatRateTypeChoice"
      },
      "VatRateTypes": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "jurisdiction": {
            "type": "string",
            "title": "Jurisdiction",
            "description": "Whose rates these are: the entity's VAT area (Liechtenstein: `CH`), or its province where it has one (`CA-ON`)."
          },
          "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "The day the rates are in force."
          },
          "rate_types": {
            "items": {
              "$ref": "#/components/schemas/VatRateTypeChoice"
            },
            "type": "array",
            "title": "Rate Types",
            "description": "Only the rate types the jurisdiction has on that day, `standard` first; empty where data-vNext has no rate for it."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "jurisdiction",
          "date",
          "rate_types"
        ],
        "title": "VatRateTypes"
      },
      "VatReasonInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why, in a few words; kept in the history."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "VatReasonInput",
        "examples": [
          {
            "reason": "Recorded on the wrong return"
          }
        ]
      },
      "VatRecomputeInput": {
        "properties": {
          "adjustments": {
            "anyOf": [
              {
                "items": {
                  "$ref": "#/components/schemas/VatAdjustment-Input"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Adjustments",
            "description": "Replaces the adjustments; omit to keep them."
          }
        },
        "type": "object",
        "title": "VatRecomputeInput",
        "examples": [
          {
            "adjustments": [
              {
                "account": "1020",
                "amount": "120.00",
                "box": "410"
              }
            ]
          }
        ]
      },
      "VatReconciliation": {
        "properties": {
          "accounts": {
            "items": {
              "$ref": "#/components/schemas/VatAccountReconciliation"
            },
            "type": "array",
            "title": "Accounts",
            "description": "Per VAT account: ledger movement and what the return took."
          },
          "ledger": {
            "type": "string",
            "title": "Ledger",
            "description": "Total ledger movement of the VAT accounts, credit minus debit."
          },
          "reported": {
            "type": "string",
            "title": "Reported",
            "description": "Total of the VAT booked that the return reports (at the booking rate: the per-account `reported` less its `tax_fx_difference`), which the settlement clears."
          },
          "other_period": {
            "type": "string",
            "title": "Other Period",
            "description": "Total of the accounts' `other_period`. VAT booked in this period whose tax point is in another period, less VAT of this period's tax points booked in another period: the date of supply moved it (goods delivered in September and invoiced in October are on the September return, in the October ledger), or the cash basis (an invoice booked in September is on the return of the period it is paid in, pro rata). Explained, not part of `unexplained`.",
            "default": "0.00"
          },
          "payable": {
            "type": "string",
            "title": "Payable",
            "description": "The return's amount payable."
          },
          "adjustments": {
            "type": "string",
            "title": "Adjustments",
            "description": "Effect of the hand-entered adjustments on the amount payable."
          },
          "computation_difference": {
            "type": "string",
            "title": "Computation Difference",
            "description": "Amount payable minus adjustments minus reported: the form computes tax from the turnover while the ledger holds each document's VAT (under the net tax rate method, the net tax rate difference). The settlement clears it to the account with the role `rounding` or `vat_net_rate_difference`."
          },
          "tax_fx_difference": {
            "type": "string",
            "title": "Tax Fx Difference",
            "description": "Part of the computational difference from foreign-currency VAT: the return takes it at the official VAT exchange rate, the ledger at the booking rate.",
            "default": "0.00"
          },
          "whole_unit_rounding": {
            "type": "string",
            "title": "Whole Unit Rounding",
            "description": "Part of the computational difference from declaring amounts in whole currency units: the amount payable minus the same return computed to the cent. Germany's UStVA drops the cents of each base and computes the tax from it; France's CA3 and Italy's Dichiarazione IVA round every amount to the euro. Zero for a form in cents (Switzerland, Spain, Canada, the Italian LIPE).",
            "default": "0.00"
          },
          "unexplained": {
            "type": "string",
            "title": "Unexplained",
            "description": "Unmapped plus untagged amounts. Finalising needs it to be zero or an `explanation`."
          },
          "settlement": {
            "items": {
              "additionalProperties": {
                "type": "string"
              },
              "type": "object"
            },
            "type": "array",
            "title": "Settlement",
            "description": "Implied settlement lines: account, signed debit."
          },
          "reconciling_items": {
            "items": {
              "$ref": "#/components/schemas/ReconcilingItem"
            },
            "type": "array",
            "title": "Reconciling Items",
            "description": "Revenue and expenses in the ledger that no turnover box of the return contains because the lines are outside the scope of VAT (a labelled reconciling item between ledger revenue and the VAT turnover). Empty when there are none."
          }
        },
        "type": "object",
        "required": [
          "accounts",
          "ledger",
          "reported",
          "payable",
          "adjustments",
          "computation_difference",
          "unexplained"
        ],
        "title": "VatReconciliation",
        "description": "Movements on the VAT accounts (credit minus debit) against the return."
      },
      "VatReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The entity's functional currency; all amounts are in it."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the period."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the period."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/VatRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "The tagged postings grouped by direction, jurisdiction, treatment and rate."
          },
          "output_tax": {
            "type": "string",
            "title": "Output Tax",
            "description": "Total output VAT of the rows."
          },
          "input_tax": {
            "type": "string",
            "title": "Input Tax",
            "description": "Total input VAT of the rows."
          },
          "net_payable": {
            "type": "string",
            "title": "Net Payable",
            "description": "Output VAT less input VAT."
          },
          "ledger_output_tax": {
            "type": "string",
            "title": "Ledger Output Tax",
            "description": "Movement on the output and reverse-charge VAT accounts."
          },
          "ledger_input_tax": {
            "type": "string",
            "title": "Ledger Input Tax",
            "description": "Movement on the input VAT accounts."
          },
          "other_period_output_tax": {
            "type": "string",
            "title": "Other Period Output Tax",
            "description": "Output VAT in `ledger_output_tax` whose tax point is in another period (the date of supply or, under the cash basis, the payment moved it), less output VAT of this period's tax points booked in another period: explained, not part of `unexplained_difference`.",
            "default": "0.00"
          },
          "other_period_input_tax": {
            "type": "string",
            "title": "Other Period Input Tax",
            "description": "The same for input VAT (`ledger_input_tax`).",
            "default": "0.00"
          },
          "unexplained_difference": {
            "type": "string",
            "title": "Unexplained Difference",
            "description": "VAT-account movements not produced by tagged subledger postings (e.g. manual journals); 0 when the report reconciles."
          },
          "reconciling_items": {
            "items": {
              "$ref": "#/components/schemas/ReconcilingItem"
            },
            "type": "array",
            "title": "Reconciling Items",
            "description": "What is in the ledger's revenue and expenses but in no VAT turnover of this report: lines outside the scope of VAT. Empty when there are none."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "start",
          "end",
          "rows",
          "output_tax",
          "input_tax",
          "net_payable",
          "ledger_output_tax",
          "ledger_input_tax",
          "unexplained_difference"
        ],
        "title": "VatReport"
      },
      "VatReturnInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code, e.g. `CH01` or `DE01` (`GET /v1/entities`)."
          },
          "kind": {
            "type": "string",
            "enum": [
              "annual_summary",
              "oss_return",
              "pst_return_bc",
              "pst_return_sk",
              "qst_return",
              "recapitulative_statement",
              "rst_return_mb",
              "vat_return"
            ],
            "title": "Kind",
            "description": "`vat_return`, `recapitulative_statement` (ZM, Modelo 349), `qst_return` (Quebec), `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary` (Modelo 390, Dichiarazione IVA) or `oss_return` (EU One-Stop Shop, union scheme). Default `vat_return`; `annual_summary` takes the period `YYYY`.",
            "default": "vat_return"
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "'2026-08', '2026-Q3', '2026-H2' or '2026'."
          },
          "adjustments": {
            "items": {
              "$ref": "#/components/schemas/VatAdjustment-Input"
            },
            "type": "array",
            "title": "Adjustments",
            "description": "Hand-entered amounts for boxes the ledger cannot fill (import VAT, Einlageentsteuerung and similar). Default: none."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "period"
        ],
        "title": "VatReturnInput",
        "examples": [
          {
            "entity": "CH01",
            "kind": "vat_return",
            "period": "2026-Q3"
          }
        ]
      },
      "VatReturnOut": {
        "properties": {
          "filing_status": {
            "type": "string",
            "enum": [
              "not_submitted",
              "paid",
              "submitted"
            ],
            "title": "Filing Status",
            "description": "`not_submitted` (not final yet, or final but not recorded as submitted), `submitted` (a person recorded the submission; a return with nothing to pay or refund stays here) or `paid` (submitted, and the linked payments cover the settled amount)."
          },
          "submitted_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted On",
            "description": "The day the return was submitted to the tax administration, as a person recorded it (ISO 8601 date); null when not submitted."
          },
          "submission_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submission Reference",
            "description": "The tax administration's reference or confirmation number, or null."
          },
          "submitted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted By",
            "description": "Who recorded the submission (type and id); null when not submitted."
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At",
            "description": "When the submission was recorded (ISO 8601 timestamp, UTC), or null."
          },
          "settled_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settled Amount",
            "description": "What the posted settlement put on the settlement account: positive is VAT to pay, negative a refund to receive (a correction: only its difference). Null when nothing was settled (not final yet, nothing to pay, a recapitulative statement)."
          },
          "paid_amount": {
            "type": "string",
            "title": "Paid Amount",
            "description": "What the linked payments cover, signed like `settled_amount`."
          },
          "payment_difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Difference",
            "description": "`settled_amount` minus `paid_amount`: what is still to pay (or receive); negative when more was paid. Null when nothing was settled."
          },
          "payments": {
            "items": {
              "$ref": "#/components/schemas/VatPaymentOut"
            },
            "type": "array",
            "title": "Payments",
            "description": "The posted entries linked as paying the return, oldest first."
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Return id (uuid); the `{return_id}` of the other operations."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity the return is for."
          },
          "kind": {
            "type": "string",
            "enum": [
              "annual_summary",
              "oss_return",
              "pst_return_bc",
              "pst_return_sk",
              "qst_return",
              "recapitulative_statement",
              "rst_return_mb",
              "vat_return"
            ],
            "title": "Kind",
            "description": "`vat_return`, `recapitulative_statement` (ZM, Modelo 349), `qst_return` (Quebec), `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary` (Modelo 390, Dichiarazione IVA) or `oss_return` (EU One-Stop Shop, union scheme)."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "Human-readable reference, e.g. `CH01-VAT-2026-Q3`; a correction appends `/n`."
          },
          "form_id": {
            "type": "string",
            "title": "Form Id",
            "description": "Id of the official form the return was computed with, e.g. `ch.estv.mwst.effective`."
          },
          "form_version": {
            "type": "string",
            "title": "Form Version",
            "description": "Version of that form (the ESTV or BMF edition it follows)."
          },
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Filing method of the form (`effective`, `net_tax_rate`) or null."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "Period label: `2026-08`, `2026-Q3`, `2026-H2` or `2026`."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the period (ISO 8601 date)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the period (ISO 8601 date)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft` (computed, can be recomputed, discarded or finalised), `pending_approval` (the settlement entry waits for a second person), `final` (settled, the period's VAT postings are locked), `amending` (a final return whose correction is open), `superseded` (replaced by a final correction) or `discarded`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the return and its amounts: the entity's functional currency."
          },
          "payable": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payable",
            "description": "Amount payable to the tax authority as a decimal string; negative is a refund (credit). Null for a recapitulative statement."
          },
          "amends_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amends Id",
            "description": "For a correction, the id of the final return it corrects; else null."
          },
          "settlement_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settlement Entry Id",
            "description": "Id of the settlement journal entry, once finalising created it; else null."
          },
          "settlement_entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settlement Entry Number",
            "description": "Number of the settlement entry once it is posted; else null."
          },
          "errors": {
            "type": "integer",
            "title": "Errors",
            "description": "Number of issues with severity `error`; a return with errors cannot be finalised."
          },
          "warnings": {
            "type": "integer",
            "title": "Warnings",
            "description": "Number of issues with severity `warning`."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time",
            "title": "Computed At",
            "description": "When the return was last computed (ISO 8601 timestamp, UTC)."
          },
          "finalized_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finalized At",
            "description": "When the return became final (ISO 8601 timestamp, UTC); null before."
          },
          "finalized_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finalized By",
            "description": "The actor that finalised it, as stored in the audit trail (type and id); null before."
          },
          "result": {
            "$ref": "#/components/schemas/VatReturnResult",
            "description": "The computed return: form, boxes, rows, reconciliation, issues."
          },
          "explanation": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Explanation",
            "description": "The explanation given when finalising, or null."
          },
          "adjustments": {
            "items": {
              "$ref": "#/components/schemas/VatAdjustment-Output"
            },
            "type": "array",
            "title": "Adjustments",
            "description": "The hand-entered adjustments the return was computed with."
          },
          "test_copy": {
            "type": "boolean",
            "title": "Test Copy",
            "description": "`true` in a test copy (`POST /v1/test-copies`): recording a submission there is a local record only, and nothing is ever filed with a tax administration.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "filing_status",
          "submitted_on",
          "submission_reference",
          "submitted_by",
          "submitted_at",
          "settled_amount",
          "paid_amount",
          "payment_difference",
          "payments",
          "id",
          "entity",
          "kind",
          "reference",
          "form_id",
          "form_version",
          "method",
          "period",
          "start",
          "end",
          "status",
          "currency",
          "payable",
          "amends_id",
          "settlement_entry_id",
          "settlement_entry_number",
          "errors",
          "warnings",
          "computed_at",
          "finalized_at",
          "finalized_by",
          "result",
          "explanation",
          "adjustments"
        ],
        "title": "VatReturnOut"
      },
      "VatReturnResult": {
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "annual_summary",
              "oss_return",
              "pst_return_bc",
              "pst_return_sk",
              "qst_return",
              "recapitulative_statement",
              "rst_return_mb",
              "vat_return"
            ],
            "title": "Kind",
            "description": "`vat_return`, `recapitulative_statement` (ZM, Modelo 349), `qst_return` (Quebec), `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary` (Modelo 390, Dichiarazione IVA) or `oss_return` (EU One-Stop Shop, union scheme)."
          },
          "form": {
            "$ref": "#/components/schemas/VatForm",
            "description": "The official form the return follows."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "entity_name": {
            "type": "string",
            "title": "Entity Name",
            "description": "Entity name."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "The entity's VAT number (Switzerland: UID)."
          },
          "tax_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Number",
            "description": "Germany: the Steuernummer from the VAT settings."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "Period label, e.g. `2026-Q3`."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the period (ISO 8601 date)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the period (ISO 8601 date)."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of all amounts: the entity's functional currency."
          },
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Filing method of the form, or null."
          },
          "boxes": {
            "items": {
              "$ref": "#/components/schemas/VatBox"
            },
            "type": "array",
            "title": "Boxes",
            "description": "Every box of the form with its amount, in form order."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/VatStatementRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "Recapitulative statement: one row per customer VAT number and kind of supply. Empty for a VAT return."
          },
          "oss_rows": {
            "items": {
              "$ref": "#/components/schemas/VatOssRow"
            },
            "type": "array",
            "title": "Oss Rows",
            "description": "One-Stop Shop return: taxable amount and VAT per member state of consumption, kind of supply and rate. Empty for other returns."
          },
          "oss_corrections": {
            "items": {
              "$ref": "#/components/schemas/VatOssCorrection"
            },
            "type": "array",
            "title": "Oss Corrections",
            "description": "One-Stop Shop return: corrections of earlier quarters (credit notes of sales of those quarters), per quarter and member state, apart from the quarter's supplies (Directive 2006/112/EC art. 369g(4)); they count in the VAT payable."
          },
          "activities": {
            "items": {
              "$ref": "#/components/schemas/VatActivity"
            },
            "type": "array",
            "title": "Activities",
            "description": "Net tax rate method: turnover and tax per approved activity."
          },
          "payable": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payable",
            "description": "Amount payable as a decimal string; negative is a credit. Null for a recapitulative statement."
          },
          "reconciliation": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/VatReconciliation"
              },
              {
                "type": "null"
              }
            ],
            "description": "The VAT accounts against the return; null for a recapitulative statement."
          },
          "adjustments": {
            "items": {
              "$ref": "#/components/schemas/VatAdjustment-Output"
            },
            "type": "array",
            "title": "Adjustments",
            "description": "The hand-entered adjustments that were applied."
          },
          "issues": {
            "items": {
              "$ref": "#/components/schemas/VatIssue"
            },
            "type": "array",
            "title": "Issues",
            "description": "Findings of the computation. A return with an `error` issue cannot be finalised."
          },
          "lines": {
            "type": "integer",
            "title": "Lines",
            "description": "Number of distinct journal lines the return draws on."
          },
          "dataset_version": {
            "type": "string",
            "title": "Dataset Version",
            "description": "Version of the reference data (forms, rates) used."
          },
          "tax_fx": {
            "items": {
              "$ref": "#/components/schemas/VatTaxFxRate"
            },
            "type": "array",
            "title": "Tax Fx",
            "description": "Official VAT exchange rates of the foreign-currency lines (CH: ESTV/BAZG, DE: BMF)."
          },
          "payment_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Code",
            "description": "Italy: the F24 tax code (codice tributo) the amount payable is paid with: 6001 to 6012 for a month, 6031 to 6033 for a quarter, 6099 for the fourth quarter paid with the annual balance; null elsewhere or when nothing is to pay."
          },
          "payment_due_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Due Date",
            "description": "Italy: the day the `payment_code` payment is due (ISO 8601 date), before the return is filed; null when there is no payment code."
          }
        },
        "type": "object",
        "required": [
          "kind",
          "form",
          "entity",
          "entity_name",
          "vat_number",
          "tax_number",
          "period",
          "start",
          "end",
          "currency",
          "method",
          "boxes",
          "payable",
          "reconciliation",
          "adjustments",
          "issues",
          "lines",
          "dataset_version"
        ],
        "title": "VatReturnResult"
      },
      "VatReturnSummary": {
        "properties": {
          "filing_status": {
            "type": "string",
            "enum": [
              "not_submitted",
              "paid",
              "submitted"
            ],
            "title": "Filing Status",
            "description": "`not_submitted` (not final yet, or final but not recorded as submitted), `submitted` (a person recorded the submission; a return with nothing to pay or refund stays here) or `paid` (submitted, and the linked payments cover the settled amount)."
          },
          "submitted_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted On",
            "description": "The day the return was submitted to the tax administration, as a person recorded it (ISO 8601 date); null when not submitted."
          },
          "submission_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submission Reference",
            "description": "The tax administration's reference or confirmation number, or null."
          },
          "submitted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted By",
            "description": "Who recorded the submission (type and id); null when not submitted."
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At",
            "description": "When the submission was recorded (ISO 8601 timestamp, UTC), or null."
          },
          "settled_amount": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settled Amount",
            "description": "What the posted settlement put on the settlement account: positive is VAT to pay, negative a refund to receive (a correction: only its difference). Null when nothing was settled (not final yet, nothing to pay, a recapitulative statement)."
          },
          "paid_amount": {
            "type": "string",
            "title": "Paid Amount",
            "description": "What the linked payments cover, signed like `settled_amount`."
          },
          "payment_difference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payment Difference",
            "description": "`settled_amount` minus `paid_amount`: what is still to pay (or receive); negative when more was paid. Null when nothing was settled."
          },
          "payments": {
            "items": {
              "$ref": "#/components/schemas/VatPaymentOut"
            },
            "type": "array",
            "title": "Payments",
            "description": "The posted entries linked as paying the return, oldest first."
          },
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Return id (uuid); the `{return_id}` of the other operations."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the entity the return is for."
          },
          "kind": {
            "type": "string",
            "enum": [
              "annual_summary",
              "oss_return",
              "pst_return_bc",
              "pst_return_sk",
              "qst_return",
              "recapitulative_statement",
              "rst_return_mb",
              "vat_return"
            ],
            "title": "Kind",
            "description": "`vat_return`, `recapitulative_statement` (ZM, Modelo 349), `qst_return` (Quebec), `pst_return_bc`, `pst_return_sk`, `rst_return_mb`, `annual_summary` (Modelo 390, Dichiarazione IVA) or `oss_return` (EU One-Stop Shop, union scheme)."
          },
          "reference": {
            "type": "string",
            "title": "Reference",
            "description": "Human-readable reference, e.g. `CH01-VAT-2026-Q3`; a correction appends `/n`."
          },
          "form_id": {
            "type": "string",
            "title": "Form Id",
            "description": "Id of the official form the return was computed with, e.g. `ch.estv.mwst.effective`."
          },
          "form_version": {
            "type": "string",
            "title": "Form Version",
            "description": "Version of that form (the ESTV or BMF edition it follows)."
          },
          "method": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Method",
            "description": "Filing method of the form (`effective`, `net_tax_rate`) or null."
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "Period label: `2026-08`, `2026-Q3`, `2026-H2` or `2026`."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "First day of the period (ISO 8601 date)."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "Last day of the period (ISO 8601 date)."
          },
          "status": {
            "type": "string",
            "title": "Status",
            "description": "`draft` (computed, can be recomputed, discarded or finalised), `pending_approval` (the settlement entry waits for a second person), `final` (settled, the period's VAT postings are locked), `amending` (a final return whose correction is open), `superseded` (replaced by a final correction) or `discarded`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Currency of the return and its amounts: the entity's functional currency."
          },
          "payable": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Payable",
            "description": "Amount payable to the tax authority as a decimal string; negative is a refund (credit). Null for a recapitulative statement."
          },
          "amends_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amends Id",
            "description": "For a correction, the id of the final return it corrects; else null."
          },
          "settlement_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settlement Entry Id",
            "description": "Id of the settlement journal entry, once finalising created it; else null."
          },
          "settlement_entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settlement Entry Number",
            "description": "Number of the settlement entry once it is posted; else null."
          },
          "errors": {
            "type": "integer",
            "title": "Errors",
            "description": "Number of issues with severity `error`; a return with errors cannot be finalised."
          },
          "warnings": {
            "type": "integer",
            "title": "Warnings",
            "description": "Number of issues with severity `warning`."
          },
          "computed_at": {
            "type": "string",
            "format": "date-time",
            "title": "Computed At",
            "description": "When the return was last computed (ISO 8601 timestamp, UTC)."
          },
          "finalized_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finalized At",
            "description": "When the return became final (ISO 8601 timestamp, UTC); null before."
          },
          "finalized_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Finalized By",
            "description": "The actor that finalised it, as stored in the audit trail (type and id); null before."
          }
        },
        "type": "object",
        "required": [
          "filing_status",
          "submitted_on",
          "submission_reference",
          "submitted_by",
          "submitted_at",
          "settled_amount",
          "paid_amount",
          "payment_difference",
          "payments",
          "id",
          "entity",
          "kind",
          "reference",
          "form_id",
          "form_version",
          "method",
          "period",
          "start",
          "end",
          "status",
          "currency",
          "payable",
          "amends_id",
          "settlement_entry_id",
          "settlement_entry_number",
          "errors",
          "warnings",
          "computed_at",
          "finalized_at",
          "finalized_by"
        ],
        "title": "VatReturnSummary"
      },
      "VatRow": {
        "properties": {
          "direction": {
            "type": "string",
            "title": "Direction",
            "description": "`sales` or `purchases`."
          },
          "jurisdiction": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Jurisdiction",
            "description": "Taxing jurisdiction, e.g. `CH` or `DE`."
          },
          "treatment": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Treatment",
            "description": "Tax treatment, e.g. `reverse_charge` or `intra_community_supply`."
          },
          "rate": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Rate",
            "description": "VAT rate in percent, as a string."
          },
          "self_assessed": {
            "type": "boolean",
            "title": "Self Assessed",
            "description": "`true` for VAT the entity accounts for itself."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "Tax base (net amount) in the functional currency."
          },
          "output_tax": {
            "type": "string",
            "title": "Output Tax",
            "description": "Output VAT owed, in the functional currency."
          },
          "input_tax": {
            "type": "string",
            "title": "Input Tax",
            "description": "Input VAT deductible, in the functional currency."
          }
        },
        "type": "object",
        "required": [
          "direction",
          "jurisdiction",
          "treatment",
          "rate",
          "self_assessed",
          "base",
          "output_tax",
          "input_tax"
        ],
        "title": "VatRow"
      },
      "VatSettingsInput": {
        "properties": {
          "method": {
            "type": "string",
            "enum": [
              "effective",
              "net_tax_rate",
              "quick",
              "standard"
            ],
            "title": "Method",
            "description": "'effective' or 'net_tax_rate' (CH), 'quick' (CA), else 'standard'."
          },
          "period": {
            "type": "string",
            "enum": [
              "half_year",
              "month",
              "quarter",
              "two_months",
              "year"
            ],
            "title": "Period",
            "description": "Return period: month, two_months (the Norwegian termin), quarter, half_year or year."
          },
          "basis": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "cash",
                  "invoice"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Basis",
            "description": "`invoice` or `cash` (VAT due when paid), where the country offers it (`cash_basis_law`). It applies to the documents posted from then on; those posted before keep theirs. Omit to keep the current basis (default `invoice`)."
          },
          "recapitulative_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "quarter"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Recapitulative Period",
            "description": "EU recapitulative statement (ZM) period."
          },
          "tax_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Number",
            "description": "DE: Steuernummer."
          },
          "registered_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registered From",
            "description": "The day the VAT registration takes effect (a company registered after its books start, or one that kept its earlier returns elsewhere): periods that end before it are not listed as due and not named as unfiled. Omit to keep it; null: since the books start."
          },
          "net_tax_rates": {
            "items": {
              "$ref": "#/components/schemas/VatNetTaxRate"
            },
            "type": "array",
            "title": "Net Tax Rates",
            "description": "The net tax rates the ESTV approved, with their activity codes. Required for `net_tax_rate` and refused for any other method. Default: none."
          },
          "settlement_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settlement Account",
            "description": "Account for the VAT payable or receivable (default: role)."
          },
          "tax_fx": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "daily",
                  "ecb_daily",
                  "monthly"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx",
            "description": "Official exchange rates for the VAT on foreign-currency documents. CH (MWSTV Art. 45): 'monthly' (ESTV monthly average, default) or 'daily' (daily selling rate); keep the method for at least a whole tax period. DE (UStG §16 Abs. 6): 'monthly' (BMF monthly average, default) or 'ecb_daily' (daily ECB rate, only with the tax office's approval). Omit to keep the current method."
          },
          "tax_fx_booking": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx Booking",
            "description": "Also book foreign-currency documents at the official VAT rate instead of the ECB fixing (only rates published when the document is posted). Omit to keep the current choice (default false)."
          },
          "filing_extension": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Filing Extension",
            "description": "DE only: the tax office granted the permanent extension of the filing deadline (Dauerfristverlängerung, UStDV §§ 46-48), so each advance return is due on the 10th of the second month after its period. Omit to keep the current choice (default false)."
          },
          "registrations": {
            "anyOf": [
              {
                "items": {
                  "type": "string"
                },
                "type": "array"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registrations",
            "description": "CA: the provinces besides its own whose sales tax the entity collects: `CA-QC`, `CA-BC`, `CA-SK`, `CA-MB`. Omit to keep the current list."
          },
          "provincial_periods": {
            "anyOf": [
              {
                "additionalProperties": {
                  "type": "string",
                  "enum": [
                    "half_year",
                    "month",
                    "quarter",
                    "two_months",
                    "year"
                  ]
                },
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Provincial Periods",
            "description": "CA: per province (`CA-BC`, `CA-SK`, `CA-MB`, `CA-QC`), the period of its sales tax return where it differs from `period`. Omit to keep the current periods."
          },
          "quick_method": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "resale",
                  "services"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Quick Method",
            "description": "CA, required with method `quick`: `resale` (goods bought for resale are at least 40% of taxable sales) or `services`."
          },
          "oss": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Oss",
            "description": "EU only: registered for the One-Stop Shop (OSS) union scheme. Omit to keep the current choice (default false)."
          },
          "oss_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Oss From",
            "description": "EU only: the day the OSS registration takes effect: the first day of the quarter after the registration, or the day of the first such sale when it is notified by the 10th of the following month (Implementing Regulation 282/2011 art. 57d). Omit to keep it; when `oss` is switched on without one, the first day of the current quarter."
          },
          "oss_destination": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Oss Destination",
            "description": "EU only: charge the customer's VAT on distance sales to consumers in other member states below the EUR 10,000 threshold too (art. 59c(3); binding for two calendar years). Omit to keep the current choice (default false)."
          }
        },
        "type": "object",
        "required": [
          "method",
          "period"
        ],
        "title": "VatSettingsInput",
        "examples": [
          {
            "method": "effective",
            "period": "quarter",
            "settlement_account": "2202"
          }
        ]
      },
      "VatSettingsOut": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "Entity country (ISO 3166-1 alpha-2); decides which methods and forms apply."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "The entity's VAT number (Switzerland: the UID, `CHE-123.456.788 MWST`, which the eCH-0217 file needs)."
          },
          "subdivision": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Subdivision",
            "description": "The entity's state or province (`CA-QC`)."
          },
          "configured": {
            "type": "boolean",
            "title": "Configured",
            "description": "False until the settings are saved: defaults apply."
          },
          "registered_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Registered From",
            "description": "The day the VAT registration takes effect: no return is due for a period that ends before it. Null: registered since the books start."
          },
          "method": {
            "type": "string",
            "enum": [
              "effective",
              "net_tax_rate",
              "quick",
              "standard"
            ],
            "title": "Method",
            "description": "`effective`, `net_tax_rate` (Switzerland), `quick` (Canada) or `standard`."
          },
          "period": {
            "type": "string",
            "enum": [
              "half_year",
              "month",
              "quarter",
              "two_months",
              "year"
            ],
            "title": "Period",
            "description": "Return period: `month`, `two_months` (the Norwegian termin), `quarter`, `half_year` or `year`."
          },
          "basis": {
            "type": "string",
            "enum": [
              "cash",
              "invoice"
            ],
            "title": "Basis",
            "description": "When VAT is due: `invoice` (with the invoice, or the date of supply where the law says so) or `cash` (when paid: the part of a document a payment, credit note or cash discount settles is reported in the period of the settlement, pro rata).",
            "default": "invoice"
          },
          "cash_basis_law": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Basis Law",
            "description": "The law that allows the cash basis in the entity's country (CH, DE, FR, GB, ES, IT); null where it is not offered."
          },
          "cash_basis_condition": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cash Basis Condition",
            "description": "The law's condition to use the cash basis (a turnover limit, an application), in the law's language; the company checks it, the ERP does not."
          },
          "cash_basis_purchases": {
            "type": "boolean",
            "title": "Cash Basis Purchases",
            "description": "Under the cash basis input VAT is reclaimed when the bill is paid too (CH, GB, ES, IT); false: it stays with the bill (DE § 15 UStG, FR; in France the VAT on services bought from a French supplier is deducted when paid on either basis, CGI art. 271).",
            "default": false
          },
          "cash_basis_open": {
            "type": "integer",
            "title": "Cash Basis Open",
            "description": "How many posted documents on the cash basis are not settled in full: their VAT is reported when they are, whatever the basis is changed to (a change of `basis` settles nothing; the law may ask for the outstanding VAT to be accounted for on leaving the cash basis, e.g. UK VAT Regulations 1995 reg. 64, which is booked by hand). French services bills, deducted when paid on either basis, do not count.",
            "default": 0
          },
          "recapitulative_period": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "month",
                  "quarter"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Recapitulative Period",
            "description": "Period of the recapitulative statement (ZM, 349): `month`, `quarter` or null."
          },
          "tax_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Number",
            "description": "Germany: the Steuernummer, or null."
          },
          "net_tax_rates": {
            "items": {
              "$ref": "#/components/schemas/VatNetTaxRate"
            },
            "type": "array",
            "title": "Net Tax Rates",
            "description": "The approved net tax rates (net tax rate method), else empty."
          },
          "settlement_account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Settlement Account",
            "description": "Code of the settlement account named in the settings; null means the account with the role `vat_settlement` is used."
          },
          "tax_fx": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "daily",
                  "ecb_daily",
                  "monthly"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Tax Fx",
            "description": "Method for official VAT exchange rates (None: not applicable)."
          },
          "tax_fx_booking": {
            "type": "boolean",
            "title": "Tax Fx Booking",
            "description": "True when foreign-currency documents are booked at the official VAT rate.",
            "default": false
          },
          "filing_extension": {
            "type": "boolean",
            "title": "Filing Extension",
            "description": "DE: true when the tax office granted the permanent extension (Dauerfristverlängerung): each advance return is due one month later.",
            "default": false
          },
          "registrations": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Registrations",
            "description": "CA: the provinces besides its own whose sales tax (QST, PST, RST) the entity collects, e.g. `CA-QC` (which adds the QST return)."
          },
          "provincial_periods": {
            "additionalProperties": {
              "type": "string",
              "enum": [
                "half_year",
                "month",
                "quarter",
                "two_months",
                "year"
              ]
            },
            "type": "object",
            "title": "Provincial Periods",
            "description": "CA: the filing period of each province's sales tax return where it differs from `period`, e.g. `{\"CA-BC\": \"month\"}`."
          },
          "quick_method": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "resale",
                  "services"
                ]
              },
              {
                "type": "null"
              }
            ],
            "title": "Quick Method",
            "description": "CA, method `quick`: the remittance rate of a business buying goods for resale (`resale`) or of a service provider (`services`); else null."
          },
          "oss_available": {
            "type": "boolean",
            "title": "Oss Available",
            "description": "The company is established in the EU, so it can register for the One-Stop Shop (`oss`, `oss_destination`).",
            "default": false
          },
          "oss": {
            "type": "boolean",
            "title": "Oss",
            "description": "EU: the company is registered for the One-Stop Shop (OSS) union scheme: it files the quarterly OSS return (kind `oss_return`) for its sales to consumers in other member states.",
            "default": false
          },
          "oss_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Oss From",
            "description": "EU: the day the OSS registration takes effect (Implementing Regulation 282/2011 art. 57d); no OSS return is due for a quarter that ends before it."
          },
          "oss_destination": {
            "type": "boolean",
            "title": "Oss Destination",
            "description": "EU: the company opted to charge the customer's VAT on distance sales of goods and electronic services to consumers in other member states even below the EUR 10,000 threshold (Directive 2006/112/EC art. 59c(3)).",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "entity",
          "country",
          "vat_number",
          "configured",
          "method",
          "period",
          "recapitulative_period",
          "tax_number",
          "net_tax_rates",
          "settlement_account"
        ],
        "title": "VatSettingsOut"
      },
      "VatStatementRow": {
        "properties": {
          "country_code": {
            "type": "string",
            "title": "Country Code",
            "description": "Country prefix of the customer's VAT number (two letters)."
          },
          "vat_id": {
            "type": "string",
            "title": "Vat Id",
            "description": "The customer's VAT number without the country prefix."
          },
          "party": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Party",
            "description": "Name of the customer with that VAT number, or null."
          },
          "box": {
            "type": "string",
            "title": "Box",
            "description": "Box id of the supply kind: goods, services or triangulation."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "Total supplies as a decimal string (whole euros on the ZM); 0 cancels a row in a ZM correction, while a 349 sustitutiva repeats every row."
          }
        },
        "type": "object",
        "required": [
          "country_code",
          "vat_id",
          "party",
          "box",
          "amount"
        ],
        "title": "VatStatementRow",
        "description": "A recapitulative statement row: one customer VAT number and kind of supply."
      },
      "VatSubmitInput": {
        "properties": {
          "submitted_on": {
            "type": "string",
            "format": "date",
            "title": "Submitted On",
            "description": "The day the return was submitted to the tax administration: not before the period ends and not in the future."
          },
          "submission_reference": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200
              },
              {
                "type": "null"
              }
            ],
            "title": "Submission Reference",
            "description": "The tax administration's reference or confirmation number. Optional."
          }
        },
        "type": "object",
        "required": [
          "submitted_on"
        ],
        "title": "VatSubmitInput",
        "examples": [
          {
            "submission_reference": "MWST-2026-123",
            "submitted_on": "2026-10-20"
          }
        ]
      },
      "VatTaxFxRate": {
        "properties": {
          "series": {
            "type": "string",
            "title": "Series",
            "description": "Official rate series, e.g. `de-vat-monthly`."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "Foreign currency the rate converts."
          },
          "period": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Period",
            "description": "Month of a monthly rate, or the daily rate's date."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "The rate as a decimal string."
          },
          "quotation": {
            "type": "string",
            "title": "Quotation",
            "description": "How the rate is quoted (units of which currency per unit of which)."
          },
          "lines": {
            "type": "integer",
            "title": "Lines",
            "description": "Number of journal lines converted with it."
          },
          "looked_up": {
            "type": "boolean",
            "title": "Looked Up",
            "description": "The rate was not published when the documents were posted; the return looked it up when it was computed."
          }
        },
        "type": "object",
        "required": [
          "series",
          "currency",
          "period",
          "rate",
          "quotation",
          "lines",
          "looked_up"
        ],
        "title": "VatTaxFxRate",
        "description": "An official VAT exchange rate the return converted foreign-currency lines at."
      },
      "VendorMatch": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Vendor code, e.g. `V-CLOUD`."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Vendor name."
          },
          "matched_by": {
            "type": "string",
            "enum": [
              "created",
              "given",
              "iban",
              "name",
              "vat_number"
            ],
            "title": "Matched By",
            "description": "How the vendor was found: `vat_number`, `iban`, `name`, `created` or `given`."
          },
          "status": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Status",
            "description": "The vendor's status: `active`, or `draft` until a second person activates it (a bill of a draft vendor stays a draft)."
          }
        },
        "type": "object",
        "required": [
          "code",
          "name",
          "matched_by"
        ],
        "title": "VendorMatch"
      },
      "VendorProposal": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "Name as printed."
          },
          "country": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "ISO 3166-1 alpha-2 country, if it could be read."
          },
          "vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vat Number",
            "description": "VAT number as printed."
          },
          "iban": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Iban",
            "description": "IBAN, only when it passes its check digits."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The bill's currency, else the entity's."
          },
          "street": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street as printed."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code as printed."
          },
          "town": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town as printed."
          },
          "email": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Email",
            "description": "E-mail address, from an e-invoice."
          }
        },
        "type": "object",
        "required": [
          "name",
          "country",
          "vat_number",
          "iban",
          "currency"
        ],
        "title": "VendorProposal",
        "description": "The vendor as the bill describes it, for a person to create (all as printed)."
      },
      "VendorStatement": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the vendor."
          },
          "party_code": {
            "type": "string",
            "title": "Party Code",
            "description": "Code of the vendor."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the vendor."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "The first day of the period."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "The last day of the period."
          },
          "language": {
            "type": "string",
            "enum": [
              "de",
              "en",
              "fr",
              "it",
              "sv"
            ],
            "title": "Language",
            "description": "The language of its PDF: the vendor's, else the one spoken in its country."
          },
          "currencies": {
            "items": {
              "$ref": "#/components/schemas/ActivityCurrency"
            },
            "type": "array",
            "title": "Currencies",
            "description": "One block per currency the vendor has movements or a balance in, by code; the vendor's own currency is among them when it has any."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The entity's functional currency."
          },
          "closing_functional": {
            "type": "string",
            "title": "Closing Functional",
            "description": "What we owe the vendor at the end of `end` in the functional currency: its lines on the payables control account, revaluations included."
          },
          "open_items": {
            "items": {
              "$ref": "#/components/schemas/StatementItem"
            },
            "type": "array",
            "title": "Open Items",
            "description": "The bills and credit notes still open at the end of `end`, oldest due date first (credit notes negative): the same open items as the payables aging."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "party_id",
          "party_code",
          "party",
          "start",
          "end",
          "language",
          "currencies",
          "functional_currency",
          "closing_functional",
          "open_items"
        ],
        "title": "VendorStatement",
        "description": "A vendor's statement: what we owe the vendor, by bill, credit note and payment."
      },
      "VersionDetail": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Version id."
          },
          "plan_id": {
            "type": "string",
            "format": "uuid",
            "title": "Plan Id",
            "description": "The plan."
          },
          "number": {
            "type": "integer",
            "title": "Number",
            "description": "The version's number within its plan, from 1."
          },
          "status": {
            "type": "string",
            "enum": [
              "approved",
              "draft",
              "submitted",
              "superseded"
            ],
            "title": "Status",
            "description": "`draft` (its lines change), `submitted` (fixed, waiting for a person to approve it or send it back), `approved` (the plan's current version) or `superseded` (approved before a later version)."
          },
          "based_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Based On",
            "description": "The version it was copied from."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "What the version is about."
          },
          "lines_digest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines Digest",
            "description": "SHA-256 of the lines as submitted: what the approval is of. Empty for a draft."
          },
          "line_count": {
            "type": "integer",
            "title": "Line Count",
            "description": "How many lines it has."
          },
          "totals": {
            "$ref": "#/components/schemas/PlanTotals",
            "description": "Its revenue, expenses and their difference."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "submitted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted By",
            "description": "Who submitted it."
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At",
            "description": "When it was submitted (UTC)."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved it."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When it was approved (UTC)."
          },
          "superseded_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Superseded At",
            "description": "When a later version was approved in its place (UTC)."
          },
          "lines": {
            "items": {
              "$ref": "#/components/schemas/PlanLineOut"
            },
            "type": "array",
            "title": "Lines",
            "description": "The lines, by account and period."
          }
        },
        "type": "object",
        "required": [
          "id",
          "plan_id",
          "number",
          "status",
          "based_on",
          "note",
          "lines_digest",
          "line_count",
          "totals",
          "created_by",
          "created_at",
          "submitted_by",
          "submitted_at",
          "approved_by",
          "approved_at",
          "superseded_at",
          "lines"
        ],
        "title": "VersionDetail",
        "examples": [
          {
            "approved_at": "2026-10-02T14:10:00Z",
            "approved_by": {
              "id": "user:bob",
              "name": "Bob",
              "type": "human"
            },
            "based_on": "7d2e3f40-5162-4c73-8d84-9ea5fb6c7d18",
            "created_at": "2026-10-01T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "id": "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607",
            "line_count": 3,
            "lines_digest": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
            "note": "After the September review",
            "number": 2,
            "plan_id": "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6",
            "status": "approved",
            "submitted_at": "2026-10-02T09:30:00Z",
            "submitted_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "totals": {
              "expenses": "21700.00",
              "net": "20300.00",
              "revenue": "42000.00"
            }
          }
        ]
      },
      "VersionInput": {
        "properties": {
          "copy_from": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Copy From",
            "description": "A version of the same plan whose lines the new draft starts with; empty to start with no lines."
          },
          "note": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "What this version is about (kept with it)."
          }
        },
        "type": "object",
        "title": "VersionInput",
        "examples": [
          {
            "copy_from": "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607",
            "note": "After the September review"
          }
        ]
      },
      "VersionOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Version id."
          },
          "plan_id": {
            "type": "string",
            "format": "uuid",
            "title": "Plan Id",
            "description": "The plan."
          },
          "number": {
            "type": "integer",
            "title": "Number",
            "description": "The version's number within its plan, from 1."
          },
          "status": {
            "type": "string",
            "enum": [
              "approved",
              "draft",
              "submitted",
              "superseded"
            ],
            "title": "Status",
            "description": "`draft` (its lines change), `submitted` (fixed, waiting for a person to approve it or send it back), `approved` (the plan's current version) or `superseded` (approved before a later version)."
          },
          "based_on": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Based On",
            "description": "The version it was copied from."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "What the version is about."
          },
          "lines_digest": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Lines Digest",
            "description": "SHA-256 of the lines as submitted: what the approval is of. Empty for a draft."
          },
          "line_count": {
            "type": "integer",
            "title": "Line Count",
            "description": "How many lines it has."
          },
          "totals": {
            "$ref": "#/components/schemas/PlanTotals",
            "description": "Its revenue, expenses and their difference."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who made it (actor object)."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          },
          "submitted_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted By",
            "description": "Who submitted it."
          },
          "submitted_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Submitted At",
            "description": "When it was submitted (UTC)."
          },
          "approved_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved By",
            "description": "Who approved it."
          },
          "approved_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approved At",
            "description": "When it was approved (UTC)."
          },
          "superseded_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Superseded At",
            "description": "When a later version was approved in its place (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "plan_id",
          "number",
          "status",
          "based_on",
          "note",
          "lines_digest",
          "line_count",
          "totals",
          "created_by",
          "created_at",
          "submitted_by",
          "submitted_at",
          "approved_by",
          "approved_at",
          "superseded_at"
        ],
        "title": "VersionOut",
        "examples": [
          {
            "approved_at": "2026-10-02T14:10:00Z",
            "approved_by": {
              "id": "user:bob",
              "name": "Bob",
              "type": "human"
            },
            "based_on": "7d2e3f40-5162-4c73-8d84-9ea5fb6c7d18",
            "created_at": "2026-10-01T08:00:00Z",
            "created_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "id": "6c1d2e3f-4051-4b62-9c73-8d94ea5fb607",
            "line_count": 3,
            "lines_digest": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
            "note": "After the September review",
            "number": 2,
            "plan_id": "5b0c1d2e-3f40-4a51-8b62-7c83d94ea5f6",
            "status": "approved",
            "submitted_at": "2026-10-02T09:30:00Z",
            "submitted_by": {
              "id": "user:alice",
              "name": "Alice",
              "type": "human"
            },
            "totals": {
              "expenses": "21700.00",
              "net": "20300.00",
              "revenue": "42000.00"
            }
          }
        ]
      },
      "Violation": {
        "properties": {
          "rule": {
            "type": "string",
            "title": "Rule",
            "description": "Rule id, e.g. `BR-DE-15`."
          },
          "severity": {
            "type": "string",
            "enum": [
              "fatal",
              "warning"
            ],
            "title": "Severity",
            "description": "`fatal` (the invoice breaks the rule) or `warning`."
          },
          "message": {
            "type": "string",
            "title": "Message",
            "description": "What is wrong."
          },
          "location": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Location",
            "description": "Where in the invoice, if known."
          }
        },
        "type": "object",
        "required": [
          "rule",
          "severity",
          "message"
        ],
        "title": "Violation"
      },
      "VisibilityInput": {
        "properties": {
          "record_visibility": {
            "type": "string",
            "enum": [
              "all",
              "own",
              "team"
            ],
            "title": "Record Visibility",
            "description": "Which sales records the person sees: `all` (every customer, contact, deal and activity), `team` (the records they or anyone in a team of theirs own) or `own` (the records they own)."
          }
        },
        "type": "object",
        "required": [
          "record_visibility"
        ],
        "title": "VisibilityInput",
        "examples": [
          {
            "record_visibility": "team"
          }
        ]
      },
      "WaitingItem": {
        "properties": {
          "contract": {
            "type": "string",
            "title": "Contract",
            "description": "Number of the revenue contract."
          },
          "contract_id": {
            "type": "string",
            "format": "uuid",
            "title": "Contract Id",
            "description": "Id of the revenue contract."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The contract's currency."
          },
          "rate_date": {
            "type": "string",
            "format": "date",
            "title": "Rate Date",
            "description": "The day whose ECB rate the run needs and does not have yet (the period end): run again once it is published."
          },
          "lines": {
            "type": "integer",
            "title": "Lines",
            "description": "Schedule lines due that wait (revenue recognised before it is billed is booked at the period end's rate); 0 when only the remeasurement waits."
          },
          "remeasurement": {
            "type": "boolean",
            "title": "Remeasurement",
            "description": "Whether the unbilled receivable's remeasurement at the closing rate waits."
          },
          "note": {
            "type": "string",
            "title": "Note",
            "description": "The same, in English words (also in `notes`)."
          },
          "note_reason": {
            "$ref": "#/components/schemas/Reason",
            "description": "`note` by code (`periodClose.recognitionNote.waiting_lines`, `waiting_remeasurement` or `waiting_both`, with `contract`, `currency`, `date` and, for lines, their `count`)."
          }
        },
        "type": "object",
        "required": [
          "contract",
          "contract_id",
          "currency",
          "rate_date",
          "lines",
          "remeasurement",
          "note",
          "note_reason"
        ],
        "title": "WaitingItem"
      },
      "WarehouseAddress": {
        "properties": {
          "street": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 70
              },
              {
                "type": "null"
              }
            ],
            "title": "Street",
            "description": "Street."
          },
          "building_number": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Building Number",
            "description": "Number."
          },
          "postal_code": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 16
              },
              {
                "type": "null"
              }
            ],
            "title": "Postal Code",
            "description": "Postal code."
          },
          "town": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 35
              },
              {
                "type": "null"
              }
            ],
            "title": "Town",
            "description": "Town."
          },
          "country": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Z]{2}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Country",
            "description": "ISO 3166 country, e.g. `CH`."
          }
        },
        "type": "object",
        "title": "WarehouseAddress"
      },
      "WarehouseInput": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code (or id) of the entity that keeps stock there."
          },
          "code": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,19}$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Code",
            "description": "Unique in the entity and never changed; left out, it is made from the name (`Lager Zürich` gives `LAGER-ZURICH`)."
          },
          "name": {
            "type": "string",
            "maxLength": 200,
            "minLength": 1,
            "title": "Name",
            "description": "What it is called."
          },
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WarehouseAddress"
              },
              {
                "type": "null"
              }
            ],
            "description": "Where it is; printed on delivery notes."
          },
          "is_default": {
            "type": "boolean",
            "title": "Is Default",
            "description": "Whether goods are taken from and put into it when nothing else is said; an entity's first warehouse is its default.",
            "default": false
          }
        },
        "type": "object",
        "required": [
          "entity",
          "name"
        ],
        "title": "WarehouseInput",
        "examples": [
          {
            "address": {
              "building_number": "201",
              "country": "CH",
              "postal_code": "8005",
              "street": "Hardstrasse",
              "town": "Zürich"
            },
            "code": "ZRH",
            "entity": "CH01",
            "name": "Lager Zürich"
          }
        ]
      },
      "WarehouseOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Warehouse id."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "Code, unique in the entity."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Name."
          },
          "address": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Address",
            "description": "Address, as recorded."
          },
          "is_default": {
            "type": "boolean",
            "title": "Is Default",
            "description": "Whether it is the entity's default warehouse."
          },
          "active": {
            "type": "boolean",
            "title": "Active",
            "description": "Whether goods move in and out of it."
          },
          "items": {
            "type": "integer",
            "title": "Items",
            "description": "How many items it holds a quantity of."
          },
          "created_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Created By",
            "description": "Who created it."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When (UTC)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "code",
          "name",
          "address",
          "is_default",
          "active",
          "items",
          "created_by",
          "created_at"
        ],
        "title": "WarehouseOut"
      },
      "WarehouseUpdate": {
        "properties": {
          "name": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 200,
                "minLength": 1
              },
              {
                "type": "null"
              }
            ],
            "title": "Name",
            "description": "New name."
          },
          "address": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/WarehouseAddress"
              },
              {
                "type": "null"
              }
            ],
            "description": "New address."
          },
          "is_default": {
            "anyOf": [
              {
                "type": "boolean",
                "const": true
              },
              {
                "type": "null"
              }
            ],
            "title": "Is Default",
            "description": "`true` makes it the default (the previous one stops being it)."
          },
          "active": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "null"
              }
            ],
            "title": "Active",
            "description": "`false`: no goods move in or out; refused while it holds stock."
          }
        },
        "type": "object",
        "title": "WarehouseUpdate",
        "examples": [
          {
            "is_default": true
          }
        ]
      },
      "WatcherOut": {
        "properties": {
          "available": {
            "type": "boolean",
            "title": "Available",
            "description": "True when the legislation watcher has run."
          },
          "run_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Run Date",
            "description": "The date of its last run (ISO 8601); null if none."
          },
          "note": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Note",
            "description": "A remark on the watcher; null if none."
          }
        },
        "type": "object",
        "required": [
          "available"
        ],
        "title": "WatcherOut"
      },
      "WinRateReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The report's currency."
          },
          "rate_day": {
            "type": "string",
            "format": "date",
            "title": "Rate Day",
            "description": "The day whose ECB fixing converts the amounts."
          },
          "fixing_date": {
            "anyOf": [
              {
                "type": "string",
                "format": "date"
              },
              {
                "type": "null"
              }
            ],
            "title": "Fixing Date",
            "description": "The fixing used; null when there is none near the day (then every other currency is in `unconverted`)."
          },
          "unconverted": {
            "items": {
              "type": "string"
            },
            "type": "array",
            "title": "Unconverted",
            "description": "Currencies left out of the converted amounts."
          },
          "closed_from": {
            "type": "string",
            "format": "date",
            "title": "Closed From",
            "description": "First close day counted."
          },
          "closed_to": {
            "type": "string",
            "format": "date",
            "title": "Closed To",
            "description": "Last close day counted."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/WinRateRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "Per owner, the most won value first."
          },
          "total": {
            "$ref": "#/components/schemas/WinRateRow",
            "description": "Every deal closed in the range."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "currency",
          "rate_day",
          "fixing_date",
          "unconverted",
          "closed_from",
          "closed_to",
          "rows",
          "total"
        ],
        "title": "WinRateReport",
        "examples": [
          {
            "closed_from": "2026-01-01",
            "closed_to": "2026-10-23",
            "currency": "CHF",
            "entity": "CH01",
            "fixing_date": "2026-10-23",
            "rate_day": "2026-10-23",
            "rows": [],
            "total": {
              "average_days_to_win": "41.5",
              "average_won": "16000.00",
              "key": "total",
              "lost": 2,
              "lost_amount": {
                "amount": "24000.00",
                "by_currency": [
                  {
                    "amount": "24000.00",
                    "currency": "CHF"
                  }
                ]
              },
              "value_win_rate": "80.0",
              "win_rate": "75.0",
              "won": 6,
              "won_amount": {
                "amount": "96000.00",
                "by_currency": [
                  {
                    "amount": "96000.00",
                    "currency": "CHF"
                  }
                ]
              }
            },
            "unconverted": []
          }
        ]
      },
      "WinRateRow": {
        "properties": {
          "key": {
            "type": "string",
            "title": "Key",
            "description": "The owner's user id, `none` for no owner, `total`."
          },
          "owner": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Person"
              },
              {
                "type": "null"
              }
            ],
            "description": "The owner."
          },
          "won": {
            "type": "integer",
            "title": "Won",
            "description": "Deals won in the range."
          },
          "lost": {
            "type": "integer",
            "title": "Lost",
            "description": "Deals lost in the range."
          },
          "won_amount": {
            "$ref": "#/components/schemas/Figure",
            "description": "Value of the deals won."
          },
          "lost_amount": {
            "$ref": "#/components/schemas/Figure",
            "description": "Value of the deals lost."
          },
          "win_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Win Rate",
            "description": "Won of won and lost, by count, in percent (one decimal); null when none closed."
          },
          "value_win_rate": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Value Win Rate",
            "description": "Won of won and lost, by converted value, in percent; null when nothing of value closed."
          },
          "average_won": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Average Won",
            "description": "The average deal won, converted."
          },
          "average_days_to_win": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Average Days To Win",
            "description": "Days from a won deal's creation to its close, on average (one decimal)."
          }
        },
        "type": "object",
        "required": [
          "key",
          "owner",
          "won",
          "lost",
          "won_amount",
          "lost_amount",
          "win_rate",
          "value_win_rate",
          "average_won",
          "average_days_to_win"
        ],
        "title": "WinRateRow"
      },
      "WithdrawInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why it is withdrawn."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "WithdrawInput",
        "examples": [
          {
            "reason": "Reconciliation found a missing statement"
          }
        ]
      },
      "WithholdingCodeOut": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The code a vendor carries, e.g. `IT-RA-20`."
          },
          "country": {
            "type": "string",
            "title": "Country",
            "description": "The country of the company that withholds it."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "The rate in percent of a bill's net amount before VAT."
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "What it is, with its legal basis."
          },
          "authority": {
            "type": "string",
            "title": "Authority",
            "description": "Whom the company pays it to, and with which return."
          }
        },
        "type": "object",
        "required": [
          "code",
          "country",
          "rate",
          "name",
          "authority"
        ],
        "title": "WithholdingCodeOut"
      },
      "WithholdingCodes": {
        "properties": {
          "country": {
            "type": "string",
            "title": "Country",
            "description": "The company's country, whose codes these are."
          },
          "codes": {
            "items": {
              "$ref": "#/components/schemas/WithholdingCodeOut"
            },
            "type": "array",
            "title": "Codes",
            "description": "The table of the company's country; a vendor may also carry `custom` with a rate of its own (a treaty rate, say). Empty where the country has none (Switzerland)."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "The account the tax kept back is booked to (role `vendor_withholding_payable`); null when the chart has none, and bills of a vendor with withholding cannot be posted until one is given that role."
          },
          "account_name": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account Name",
            "description": "Its name."
          }
        },
        "type": "object",
        "required": [
          "country",
          "codes",
          "account",
          "account_name"
        ],
        "title": "WithholdingCodes",
        "description": "The codes the company's vendors can carry, and where the tax is booked."
      },
      "WithholdingReport": {
        "properties": {
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "The company's code."
          },
          "functional_currency": {
            "type": "string",
            "title": "Functional Currency",
            "description": "The currency of the `_functional` amounts."
          },
          "start": {
            "type": "string",
            "format": "date",
            "title": "Start",
            "description": "The first day of the period."
          },
          "end": {
            "type": "string",
            "format": "date",
            "title": "End",
            "description": "The last day of the period."
          },
          "basis": {
            "type": "string",
            "enum": [
              "bill_date",
              "payment_date"
            ],
            "title": "Basis",
            "description": "`bill_date`: the tax of the bills dated in the period and of the cash discounts taken in it, as booked on the account; `payment_date`: the part the payments made in the period released, at their rates (Italy, Germany, Spain and the US owe the tax for the month or quarter the vendor is paid)."
          },
          "account": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Account",
            "description": "The withholding tax payable account."
          },
          "rows": {
            "items": {
              "$ref": "#/components/schemas/WithholdingRow"
            },
            "type": "array",
            "title": "Rows",
            "description": "The documents, oldest first."
          },
          "totals": {
            "items": {
              "$ref": "#/components/schemas/WithholdingTotal"
            },
            "type": "array",
            "title": "Totals",
            "description": "Per code and currency."
          },
          "total_functional": {
            "type": "string",
            "title": "Total Functional",
            "description": "All the tax counted, in the functional currency: by bill date, what the period's bills and cash discounts booked on the withholding tax account; by payment date, what the period's payments released at their rates."
          }
        },
        "type": "object",
        "required": [
          "entity",
          "functional_currency",
          "start",
          "end",
          "basis",
          "account",
          "rows",
          "totals",
          "total_functional"
        ],
        "title": "WithholdingReport",
        "description": "The withholding tax kept back from vendors in a period, to file it and pay the authority."
      },
      "WithholdingRow": {
        "properties": {
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "The bill or credit note."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Our number of it, e.g. `BILL-2026-000012`."
          },
          "their_reference": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Their Reference",
            "description": "The vendor's own invoice number."
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "`purchase_bill`, `purchase_credit_note`, or (by bill date) `cash_discount`: a cash discount taken on the bill, which reduced the base and the tax in proportion."
          },
          "document_date": {
            "type": "string",
            "format": "date",
            "title": "Document Date",
            "description": "The bill's date, when the tax was booked; for `cash_discount` the day of the payment that took it."
          },
          "vendor": {
            "type": "string",
            "title": "Vendor",
            "description": "The vendor's code."
          },
          "vendor_name": {
            "type": "string",
            "title": "Vendor Name",
            "description": "The vendor's name."
          },
          "vendor_country": {
            "type": "string",
            "title": "Vendor Country",
            "description": "The vendor's country."
          },
          "vendor_vat_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Vendor Vat Number",
            "description": "The vendor's VAT or tax number."
          },
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The withholding code, e.g. `IT-RA-20`, or `custom`."
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "What the code is; for `custom`, the vendor's own rate."
          },
          "authority": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Authority",
            "description": "Whom the tax is paid to; null for `custom`."
          },
          "rate": {
            "type": "string",
            "title": "Rate",
            "description": "The rate in percent."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The document currency; the amounts below are in it."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "The net amount before VAT the tax was taken on; negative on a credit note and a cash discount. By payment date: less what cash discounts took off up to the period's end (the figure of the vendor's certificate)."
          },
          "withheld": {
            "type": "string",
            "title": "Withheld",
            "description": "The tax the document kept back, base times rate; negative on a credit note and a cash discount (they give tax back). By payment date: less what cash discounts took off up to the period's end."
          },
          "paid": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Paid",
            "description": "`basis=payment_date`: what payments to the vendor in the period settled on the bill; null by bill date."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The tax this report counts in the period: by bill date all of `withheld`; by payment date the part of it the payments in the period released (the tax times what was paid over what the bill left to pay, the last payment all that is left), net of what their cash discounts took off."
          },
          "amount_functional": {
            "type": "string",
            "title": "Amount Functional",
            "description": "`amount` in the company's functional currency: by bill date at the rate the bill was booked at; by payment date at the rate of each payment's day, as the authority is owed it (the payment moves it to that rate on the withholding tax account)."
          }
        },
        "type": "object",
        "required": [
          "document_id",
          "number",
          "their_reference",
          "kind",
          "document_date",
          "vendor",
          "vendor_name",
          "vendor_country",
          "vendor_vat_number",
          "code",
          "description",
          "authority",
          "rate",
          "currency",
          "base",
          "withheld",
          "paid",
          "amount",
          "amount_functional"
        ],
        "title": "WithholdingRow",
        "description": "One bill or vendor credit note that kept withholding tax back, or a cash discount that\ntook tax off a bill."
      },
      "WithholdingTotal": {
        "properties": {
          "code": {
            "type": "string",
            "title": "Code",
            "description": "The withholding code."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "The document currency of `amount`."
          },
          "documents": {
            "type": "integer",
            "title": "Documents",
            "description": "How many rows: bills, credit notes and cash discounts."
          },
          "base": {
            "type": "string",
            "title": "Base",
            "description": "Their net amounts the tax was taken on."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "The tax counted, in `currency`."
          },
          "amount_functional": {
            "type": "string",
            "title": "Amount Functional",
            "description": "The same in the functional currency."
          }
        },
        "type": "object",
        "required": [
          "code",
          "currency",
          "documents",
          "base",
          "amount",
          "amount_functional"
        ],
        "title": "WithholdingTotal"
      },
      "WriteOffInput": {
        "properties": {
          "write_off_date": {
            "type": "string",
            "format": "date",
            "title": "Write Off Date",
            "description": "The day of the write-off (ISO 8601): on or after the invoice and its latest settlement, not after today, in an open period."
          },
          "amount": {
            "anyOf": [
              {
                "type": "number",
                "exclusiveMinimum": 0.0
              },
              {
                "type": "string",
                "pattern": "^(?!^[-+.]*$)[+-]?0*\\d*\\.?\\d*$"
              },
              {
                "type": "null"
              }
            ],
            "title": "Amount",
            "description": "What to write off, VAT included, in the invoice's currency; at most what is open. Default: all of what is open."
          },
          "vat_treatment": {
            "type": "string",
            "enum": [
              "correct",
              "keep"
            ],
            "title": "Vat Treatment",
            "description": "`correct`: the loss is final (bankruptcy closed, nothing more to collect), so the output VAT on the amount is corrected now and the VAT return of the period shows the reduction; `keep`: the loss is not final yet, the VAT stays owed and the whole amount goes to the bad-debt account (its VAT can be corrected later, once the loss is final). A company that reports VAT when paid (cash basis) always corrects: no VAT is owed on money never received, so `keep` is refused there (`write_off_keep_cash_basis`)."
          },
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why the receivable cannot be collected; kept with the write-off and shown to the person who approves it."
          }
        },
        "type": "object",
        "required": [
          "write_off_date",
          "vat_treatment",
          "reason"
        ],
        "title": "WriteOffInput",
        "examples": [
          {
            "amount": "540.50",
            "reason": "Customer bankrupt; the receiver confirmed no dividend.",
            "vat_treatment": "correct",
            "write_off_date": "2026-10-12"
          }
        ]
      },
      "WriteOffOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the write-off."
          },
          "number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Number",
            "description": "Its number once posted, e.g. `WO-2026-000001`; none while it waits."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Code of the company."
          },
          "document_id": {
            "type": "string",
            "format": "uuid",
            "title": "Document Id",
            "description": "Id of the invoice written off."
          },
          "document_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Document Number",
            "description": "Number of the invoice written off."
          },
          "party_id": {
            "type": "string",
            "format": "uuid",
            "title": "Party Id",
            "description": "Id of the customer."
          },
          "party": {
            "type": "string",
            "title": "Party",
            "description": "Name of the customer."
          },
          "write_off_date": {
            "type": "string",
            "format": "date",
            "title": "Write Off Date",
            "description": "The day of the write-off."
          },
          "currency": {
            "type": "string",
            "title": "Currency",
            "description": "ISO 4217 currency of the invoice and the amounts."
          },
          "amount": {
            "type": "string",
            "title": "Amount",
            "description": "What was written off, VAT included."
          },
          "vat_treatment": {
            "type": "string",
            "enum": [
              "correct",
              "keep"
            ],
            "title": "Vat Treatment",
            "description": "`correct` (the VAT on it was corrected) or `keep` (the VAT stays owed)."
          },
          "tax_amount": {
            "type": "string",
            "title": "Tax Amount",
            "description": "The output VAT corrected, in the invoice's currency; 0 when kept."
          },
          "functional_amount": {
            "type": "string",
            "title": "Functional Amount",
            "description": "What it took off the receivable in the functional currency, at the rate the invoice is carried at."
          },
          "reason": {
            "type": "string",
            "title": "Reason",
            "description": "Why it was written off."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending_approval",
              "posted",
              "rejected"
            ],
            "title": "Status",
            "description": "`pending_approval` (a second person decides it on Approvals; until then it reserves its amount on the invoice), `posted` or `rejected`."
          },
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "Its journal entry."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "title": "Created At",
            "description": "When it was asked for (UTC)."
          },
          "recovered": {
            "type": "string",
            "title": "Recovered",
            "description": "What was received after the write-off (recoveries posted or waiting), in the invoice's currency.",
            "default": "0.00"
          },
          "vat_corrected_later": {
            "type": "boolean",
            "title": "Vat Corrected Later",
            "description": "Whether the VAT it kept was corrected later, once the loss was final (a `vat_correction` follow-up posted or waiting).",
            "default": false
          },
          "follow_ups": {
            "items": {
              "$ref": "#/components/schemas/FollowUpOut"
            },
            "type": "array",
            "title": "Follow Ups",
            "description": "Money received after it and the VAT corrected later, oldest first (rejected ones too)."
          }
        },
        "type": "object",
        "required": [
          "id",
          "number",
          "entity",
          "document_id",
          "document_number",
          "party_id",
          "party",
          "write_off_date",
          "currency",
          "amount",
          "vat_treatment",
          "tax_amount",
          "functional_amount",
          "reason",
          "status",
          "journal_entry_id",
          "created_at"
        ],
        "title": "WriteOffOut",
        "description": "A write-off of all or part of what was open on a sales invoice."
      },
      "WriteOffResult": {
        "properties": {
          "write_off": {
            "$ref": "#/components/schemas/WriteOffOut",
            "description": "The write-off, waiting for a second person."
          },
          "submit": {
            "$ref": "#/components/schemas/SubmitResult",
            "description": "How its entry was submitted: always `pending_approval`, with the `approval_id` a second person decides."
          }
        },
        "type": "object",
        "required": [
          "write_off",
          "submit"
        ],
        "title": "WriteOffResult"
      },
      "XRechnungOut": {
        "properties": {
          "filename": {
            "type": "string",
            "title": "Filename",
            "description": "Name of the XRechnung file, e.g. `xrechnung-INV-2026-000001.xml`."
          },
          "valid": {
            "type": "boolean",
            "title": "Valid",
            "description": "`true` when no fatal rule is broken."
          },
          "violations": {
            "items": {
              "$ref": "#/components/schemas/Violation"
            },
            "type": "array",
            "title": "Violations",
            "description": "The rules the invoice breaks, by rule id."
          },
          "invoice": {
            "$ref": "#/components/schemas/Invoice",
            "description": "The invoice in EN 16931 terms as written to the file."
          }
        },
        "type": "object",
        "required": [
          "filename",
          "valid",
          "violations",
          "invoice"
        ],
        "title": "XRechnungOut"
      },
      "YearCloseOut": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the year close."
          },
          "entity": {
            "type": "string",
            "title": "Entity",
            "description": "Entity code."
          },
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year it closes."
          },
          "kind": {
            "type": "string",
            "enum": [
              "catch_up",
              "year_end"
            ],
            "title": "Kind",
            "description": "`year_end` (the closing entry of the year) or `catch_up` (the entry that closes the years booked before the books were closed)."
          },
          "status": {
            "type": "string",
            "enum": [
              "cancelled",
              "closed",
              "pending",
              "reopened"
            ],
            "title": "Status",
            "description": "`pending` (the closing entry waits for a second person; the year is locked), `closed` (posted; the year is locked), `reopened` (reversed by a reopening) or `cancelled` (withdrawn or rejected; the lock is lifted)."
          },
          "result": {
            "type": "string",
            "title": "Result",
            "description": "The result of the year, profit positive."
          },
          "appropriated": {
            "type": "string",
            "title": "Appropriated",
            "description": "What shareholders' resolutions have appropriated so far, signed like the result."
          },
          "remainder": {
            "type": "string",
            "title": "Remainder",
            "description": "`result` less `appropriated`: what is left to resolve."
          },
          "appropriation_overdue": {
            "type": "boolean",
            "title": "Appropriation Overdue",
            "description": "True for a Swiss entity whose general meeting is due (six months after the year end, Art. 699 para. 2 OR) while a remainder is unappropriated."
          },
          "journal_entry_id": {
            "type": "string",
            "format": "uuid",
            "title": "Journal Entry Id",
            "description": "The closing entry."
          },
          "entry_number": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Entry Number",
            "description": "Its number once posted."
          },
          "entry_status": {
            "type": "string",
            "title": "Entry Status",
            "description": "`pending_approval`, `posted` or `rejected`."
          },
          "approval_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Approval Id",
            "description": "The approval request of a closing entry that waits for a second person: `POST /v1/approvals/{approval_id}/approve` (not by the person who proposed it)."
          },
          "totals_digest": {
            "type": "string",
            "title": "Totals Digest",
            "description": "SHA-256 of the account totals it was computed from."
          },
          "proposed_by": {
            "additionalProperties": true,
            "type": "object",
            "title": "Proposed By",
            "description": "Who proposed it, as an actor object."
          },
          "proposed_at": {
            "type": "string",
            "format": "date-time",
            "title": "Proposed At",
            "description": "When it was proposed (UTC)."
          },
          "closed_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed By",
            "description": "Who posted it; null until closed."
          },
          "closed_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Closed At",
            "description": "When it was posted; null until closed."
          },
          "cancelled_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancelled By",
            "description": "Who cancelled it, if cancelled."
          },
          "cancelled_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancelled At",
            "description": "When it was cancelled, if cancelled."
          },
          "cancel_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Cancel Reason",
            "description": "Why it was cancelled, if cancelled."
          },
          "reopened_by": {
            "anyOf": [
              {
                "additionalProperties": true,
                "type": "object"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reopened By",
            "description": "Who reopened it, if reopened."
          },
          "reopened_at": {
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reopened At",
            "description": "When it was reopened, if reopened."
          },
          "reopen_reason": {
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reopen Reason",
            "description": "Why it was reopened, if reopened."
          },
          "reversal_entry_id": {
            "anyOf": [
              {
                "type": "string",
                "format": "uuid"
              },
              {
                "type": "null"
              }
            ],
            "title": "Reversal Entry Id",
            "description": "The reversal of the closing entry that a reopening posted."
          },
          "detail": {
            "additionalProperties": true,
            "type": "object",
            "title": "Detail",
            "description": "For a catch-up, the result of each earlier year; empty for a year-end close."
          },
          "appropriations": {
            "items": {
              "$ref": "#/components/schemas/AppropriationOut"
            },
            "type": "array",
            "title": "Appropriations",
            "description": "The resolutions booked against its result, oldest first."
          }
        },
        "type": "object",
        "required": [
          "id",
          "entity",
          "fiscal_year",
          "kind",
          "status",
          "result",
          "appropriated",
          "remainder",
          "appropriation_overdue",
          "journal_entry_id",
          "entry_number",
          "entry_status",
          "approval_id",
          "totals_digest",
          "proposed_by",
          "proposed_at",
          "closed_by",
          "closed_at",
          "cancelled_by",
          "cancelled_at",
          "cancel_reason",
          "reopened_by",
          "reopened_at",
          "reopen_reason",
          "reversal_entry_id",
          "detail",
          "appropriations"
        ],
        "title": "YearCloseOut"
      },
      "YearCloseSummary": {
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "Id of the year close."
          },
          "kind": {
            "type": "string",
            "enum": [
              "catch_up",
              "year_end"
            ],
            "title": "Kind",
            "description": "`year_end` or `catch_up`."
          },
          "status": {
            "type": "string",
            "enum": [
              "cancelled",
              "closed",
              "pending",
              "reopened"
            ],
            "title": "Status",
            "description": "`pending`, `closed`, `reopened` or `cancelled`."
          },
          "result": {
            "type": "string",
            "title": "Result",
            "description": "The result of the year, profit positive."
          },
          "appropriated": {
            "type": "string",
            "title": "Appropriated",
            "description": "What is appropriated so far, signed like the result."
          },
          "remainder": {
            "type": "string",
            "title": "Remainder",
            "description": "What is left to appropriate."
          },
          "appropriation_overdue": {
            "type": "boolean",
            "title": "Appropriation Overdue",
            "description": "True when the general meeting is overdue and a remainder is unappropriated."
          }
        },
        "type": "object",
        "required": [
          "id",
          "kind",
          "status",
          "result",
          "appropriated",
          "remainder",
          "appropriation_overdue"
        ],
        "title": "YearCloseSummary",
        "description": "The close of a fiscal year as the list of fiscal years shows it."
      },
      "YearOutlook": {
        "properties": {
          "fiscal_year": {
            "type": "integer",
            "title": "Fiscal Year",
            "description": "The fiscal year."
          },
          "actual": {
            "type": "string",
            "title": "Actual",
            "description": "What was posted in its closed periods (compared ones)."
          },
          "plan_rest": {
            "type": "string",
            "title": "Plan Rest",
            "description": "The plan of its periods that are not closed."
          },
          "outlook": {
            "type": "string",
            "title": "Outlook",
            "description": "Actual plus the plan of the rest: where the year lands."
          },
          "plan": {
            "type": "string",
            "title": "Plan",
            "description": "The plan of all its compared periods, for reference."
          }
        },
        "type": "object",
        "required": [
          "fiscal_year",
          "actual",
          "plan_rest",
          "outlook",
          "plan"
        ],
        "title": "YearOutlook"
      },
      "erp__features__close__contracts__year_close__ReasonInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 1000,
            "minLength": 3,
            "title": "Reason",
            "description": "Why; kept in the audit trail and on the close."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "ReasonInput",
        "examples": [
          {
            "reason": "The audit found a missing accrual"
          }
        ]
      },
      "erp__features__crm__contracts__sales__ReasonInput": {
        "properties": {
          "reason": {
            "type": "string",
            "maxLength": 500,
            "minLength": 1,
            "title": "Reason",
            "description": "Why; kept on the document."
          }
        },
        "type": "object",
        "required": [
          "reason"
        ],
        "title": "ReasonInput",
        "examples": [
          {
            "reason": "Customer chose another offer"
          }
        ]
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer erp_<prefix>_<secret>`, an API key (`POST /v1/api-keys`)."
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "The same API key in the `X-API-Key` header."
      },
      "platformAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer erpp_<prefix>_<secret>`, a platform key (issued with `erp platform-key create`). It is accepted only by the `/v1/platform` operations, which accept nothing else."
      }
    }
  },
  "tags": [
    {
      "name": "organization",
      "description": "The organization of the credential, its API keys and your own profile."
    },
    {
      "name": "search",
      "description": "Find an invoice, bill, credit note, purchase order, journal entry, payment, customer or vendor by its number, a reference or a name, in every entity."
    },
    {
      "name": "users",
      "description": "People who sign in to the web UI, their roles, and the UI's sign-in endpoints."
    },
    {
      "name": "setup",
      "description": "Legal entities, charts of accounts, fiscal years and periods."
    },
    {
      "name": "imports",
      "description": "Import customers, vendors, accounts, opening balances and open items from CSV or Excel: dry run, all-or-nothing commit, templates."
    },
    {
      "name": "journals",
      "description": "Manual journal entries: create, submit through the approval policy, reverse."
    },
    {
      "name": "dimensions",
      "description": "Cost centres, profit centres and projects: the values postings are analysed by, the accounts that require them, and the results by value."
    },
    {
      "name": "recurring journals",
      "description": "Journal entries that repeat (rent, allocations, accruals) monthly, quarterly or yearly, optionally reversed on the first day of the next period: posted on demand by a run that is idempotent, each entry through the approval policy."
    },
    {
      "name": "approvals",
      "description": "The queue of actions waiting for a second person, and the decision."
    },
    {
      "name": "approval policy",
      "description": "The decision table that says who may post, approve or release what."
    },
    {
      "name": "documents",
      "description": "Sales invoices, purchase bills and credit notes: draft, submit, void, history; the invoice PDF, ZUGFeRD / Factur-X, sending by e-mail or recording a hand-over; the files of a document: originals, archived outputs and attachments."
    },
    {
      "name": "purchase-orders",
      "description": "Purchase orders, receipts, matching of bills to orders and the matching tolerances."
    },
    {
      "name": "parties",
      "description": "Customers and vendors: master data, activation, bank details."
    },
    {
      "name": "payments",
      "description": "Receipts and payments with allocations, payment proposals and payment runs."
    },
    {
      "name": "swiss payments",
      "description": "Bank accounts, QR-bills and payment files (pain.001)."
    },
    {
      "name": "banking",
      "description": "Bank statement import (camt.053, camt.054, CSV), matching and posting."
    },
    {
      "name": "e-invoicing",
      "description": "XRechnung and ZUGFeRD / Factur-X: check, receive as a draft bill, issue."
    },
    {
      "name": "close",
      "description": "Period-end: depreciation, FX revaluation, deferred tax, checklist, close, reopen."
    },
    {
      "name": "close tracker",
      "description": "The close calendar of an entity (owner, the working day each step is due on), its own month-end tasks and the close status of a period: the steps, the tasks, who did what and what is overdue."
    },
    {
      "name": "crm",
      "description": "Customer relationships: the deals of an entity's pipeline (opportunities with a customer or a prospect, their stages and probability), the timeline of calls, meetings, notes and tasks, the pipeline by stage, and the sales reports: the pipeline by owner and month, the win rate, each person's activity, quotas and the forecast; the people at customers and vendors (contacts, erased on request) and the organization's own fields on companies, contacts and deals. Nothing here posts."
    },
    {
      "name": "notifications",
      "description": "Your notification centre: tasks given to you, due or overdue, deals of yours assigned, won or lost, your approval requests decided; which of them also come by e-mail."
    },
    {
      "name": "webhooks",
      "description": "Other systems told of events (deal won, invoice posted, payment received ...): the endpoints, signed messages (Standard Webhooks), retries and the delivery log."
    },
    {
      "name": "support",
      "description": "The support desk: queues with an inbox address, service levels and working hours; cases from e-mail, calls and agents, with their customer and contact, the person working them, notes, draft replies a person sends, and when the first reply and the resolution are due or were breached. Nothing here posts."
    },
    {
      "name": "products",
      "description": "What the entities sell: products with the revenue account, supply type and VAT rate type their invoice lines take, list prices by currency from a day, and the standalone selling prices a person records with their basis. Nothing here posts."
    },
    {
      "name": "price lists",
      "description": "Prices per customer and currency: an entity's price lists, each in one currency, with prices of its products in volume tiers from a day, and the list each customer takes in a currency. A sales line proposes the customer's price before the list price; it still states its own. Nothing here posts."
    },
    {
      "name": "inventory",
      "description": "Stock: warehouses, the products kept in stock with their inventory and cost of goods sold accounts, adjustments, transfers between warehouses, stock counts, the stock postings with their journal entries, and the valuation at moving average tied to the inventory accounts."
    },
    {
      "name": "goods received",
      "description": "Goods received on purchase orders and the GR/IR account (goods received, not invoiced): what a receipt posts, per order line what was received, billed and is still open, and the open items on a day tied to the GR/IR account."
    },
    {
      "name": "delivery notes",
      "description": "Delivery notes: goods shipped to a customer from a warehouse, posted at moving average cost (Dr cost of goods sold / Cr inventory), their PDF, invoicing them, and what is delivered but not yet invoiced."
    },
    {
      "name": "year-end close",
      "description": "Close a fiscal year into the annual-result account, lock it, reopen it by reversal, book the shareholders' resolution on the result (appropriation) and catch up the years booked before the books were closed."
    },
    {
      "name": "dunning",
      "description": "Customer statements: the open items of one customer on a day, tied to the receivables control account, as JSON, CSV or a PDF in the customer's language, archived with its hash when a person issues it. Vendor statements: the movements on a vendor's account between two days with the running balance. Reminder letters: which customers are due one, the letter in their language, archived, sent or recorded as handed over. No fee and no interest; nothing here posts."
    },
    {
      "name": "consolidation",
      "description": "Group consolidation: the group structure and its approval, a run that translates the subsidiaries to the reporting currency (IAS 21) and aggregates them, the translated trial balances, the group statements before eliminations and the translation reserve roll-forward."
    },
    {
      "name": "intercompany",
      "description": "Trade between two entities of one organization: the approved relationship (with its VAT group and transfer-pricing record), the draft bill an invoice creates in the counterpart and its acceptance, loans with their interest, group dividends, the settlements, and the reconciliation of the two sides."
    },
    {
      "name": "exchange rates",
      "description": "ECB rates against the entity's currency, cross rates, history, a converter, the official VAT rates next to them, and the foreign-currency exposure a revaluation would remeasure. Reference data only: nothing here changes the books."
    },
    {
      "name": "reports",
      "description": "Trial balance, profit and loss, balance sheet, general ledger, aging, VAT report."
    },
    {
      "name": "audit files",
      "description": "The files a company hands its auditors, for one fiscal year: the FEC (fichier des écritures comptables) in France, the GoBD data carrier (Datenträgerüberlassung, CSV with index.xml) in Germany, the OECD SAF-T 2.0 XML elsewhere, and the audit evidence pack (AICPA Audit Data Standards) everywhere."
    },
    {
      "name": "analytics",
      "description": "Close analytics: period flux and unusual entries."
    },
    {
      "name": "vat returns",
      "description": "VAT settings and returns (CH, DE; Canada's GST/HST and QST): compute, finalise, amend, settle."
    },
    {
      "name": "settings",
      "description": "The organization's reference-data sources and their status."
    },
    {
      "name": "platform",
      "description": "For the platform operator only, with a platform key or a session of the operator portal: provision organizations, list and open them, suspend and reactivate them, invite their administrators, mark a demo, export an organization's data for its offboarding, read the audit record. A tenant's keys and sessions do not work here, and a platform credential works nowhere else."
    },
    {
      "name": "agents",
      "description": "Built-in agents (bill capture, reconciliation, close review, assistant, Q&A)."
    },
    {
      "name": "audit",
      "description": "The audit trail, the hash chain verification and the archive export for auditors."
    },
    {
      "name": "exports",
      "description": "The complete package of the organization's own data for its archive: every table as CSV and JSON, reports, stored files, hash-chain verification and hashes. Started by an administrator, built asynchronously, downloaded or fetched through a signed link."
    },
    {
      "name": "test copies",
      "description": "A test organization with the organization's setup (companies, chart of accounts, customers, vendors, products, people) and empty books, to try things out without touching the real ones; removing one; and sample data for a test organization."
    },
    {
      "name": "meta",
      "description": "Health check."
    },
    {
      "name": "recurring invoices",
      "description": "Templates of invoices that repeat (monthly, quarterly, yearly): created as drafts, activated by a human after a second person approves the terms, and made on demand by a run that is idempotent and never makes a period twice."
    },
    {
      "name": "revenue contracts",
      "description": "IFRS 15 revenue contracts: the customer, the transaction price and the performance obligations with their standalone selling prices; a second person approves the terms, which allocates the price and writes the recognition schedule, and a person records when a point-in-time obligation is satisfied. Nothing here posts yet."
    },
    {
      "name": "subscriptions",
      "description": "Subscriptions: a committed term of recurring products billed monthly, quarterly or yearly, in advance or in arrears. A second person approves the terms, which activates the term's revenue contract; the run bills each period against the contract's obligations."
    },
    {
      "name": "capacity",
      "description": "Capacity: products sold by the time slot (a room by the night, a meeting room or a person's day by the day, people's time by the hour) with the units of each slot, what is free on each day, and bookings that never take more than is free. Nothing here posts."
    },
    {
      "name": "fixed assets",
      "description": "Assets, depreciation books, disposals and book-tax differences."
    },
    {
      "name": "saved reports",
      "description": "Lists and reports a person builds (or asks the assistant for) and keeps: run, shared, pinned to Home and e-mailed on a schedule, each reader seeing what they may."
    },
    {
      "name": "hospitality",
      "description": "Hospitality: room types let by the night (their rooms kept as capacity, so a night is never let twice), seasonal rates, what a stay costs, and stays from reservation through check-in to check-out, which drafts the stay's sales invoice."
    },
    {
      "name": "cash-forecast",
      "description": "Cash forecast: today's cash and what comes in and goes out in each of the next 13 weeks, from open invoices and bills at each party's payment habit, payments not posted yet and what recurring invoices, subscriptions and recurring journals will make; with its lowest point and what changed since the forecast of an earlier week. Nothing here posts."
    },
    {
      "name": "plans",
      "description": "Budgets and rolling forecasts: plans with versions that a person approves, lines by account and period, and the comparison with what was posted. Never posted to the ledger."
    },
    {
      "name": "rolling-forecast",
      "description": "Rolling forecast: the forecast of profit and loss every company has for the next 12 periods, made by the system and rolled after each close from actuals and the run rate, never below what is already scheduled. Its versions are plans (`plans`)."
    },
    {
      "name": "roles",
      "description": "Roles in plain words: the ready-made roles and the organization's own, each a person's rights, the areas of the app it opens and which sales records its people see; who has which, what a person can open and do, and the rights nobody used for 90 days."
    },
    {
      "name": "company sign-in",
      "description": "Company sign-in: the organization's own identity provider (Okta, Microsoft Entra ID or any OpenID Connect provider), the e-mail domains whose people sign in there, and the sign-in itself, which the passkey step follows."
    },
    {
      "name": "expenses",
      "description": "Expenses: a receipt's photo becomes an expense whose category, VAT, project and card fill in by themselves; the AI reviewer checks it against the company's expense policy, so a person sees only what it flags; it is booked as a bill and paid back in the next payment run. Company cards and their lines, matched to the receipts."
    },
    {
      "name": "vat returns",
      "description": "VAT settings and returns (CH, DE; Canada's GST/HST and QST): compute, finalise, amend, settle."
    },
    {
      "name": "shopify",
      "description": "Shopify: a company's online shop connected with an app of its own; every 5 minutes the shop's products come in as the company's products and its orders as sales orders, invoiced when sent and paid to the payment provider's balance; a drop shipper's suppliers get a purchase order for what they ship."
    },
    {
      "name": "addresses",
      "description": "Address help: whole addresses suggested as people type, from Google's Places API through the ERP (only the text typed and the country reach Google), the parts of the one chosen, and the towns of a postal code from open data shipped with Stabiso. Nothing is stored."
    }
  ]
}
